diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:29:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:29:52 -0400 |
commit | ad9471752ebae25daa133b4e5d9299809c35e155 (patch) | |
tree | dfcc75d7ee75ef0465c109423885c4326ccf9b9f /drivers/scsi/mpt2sas | |
parent | 6c1b8d94bcc1882e451d0e7a28a4a5253f4970ab (diff) | |
parent | 6ad11eaa8a689a27e0c99905bcf800a37cd432a0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (110 commits)
[SCSI] qla2xxx: Refactor call to qla2xxx_read_sfp for thermal temperature.
[SCSI] qla2xxx: Unify the read/write sfp mailbox command routines.
[SCSI] qla2xxx: Clear complete initialization control block.
[SCSI] qla2xxx: Allow an override of the registered maximum LUN.
[SCSI] qla2xxx: Add host number in reset and quiescent message logs.
[SCSI] qla2xxx: Correctly read sfp single byte mailbox register.
[SCSI] qla2xxx: Add qla82xx_rom_unlock() function.
[SCSI] qla2xxx: Log if qla82xx firmware fails to load from flash.
[SCSI] qla2xxx: Use passed in host to initialize local scsi_qla_host in queuecommand function
[SCSI] qla2xxx: Correct buffer start in edc sysfs debug print.
[SCSI] qla2xxx: Update firmware version after flash update for ISP82xx.
[SCSI] qla2xxx: Fix hang during driver unload when vport is active.
[SCSI] qla2xxx: Properly set the dsd_list_len for dsd_chaining in cmd type 6.
[SCSI] qla2xxx: Fix virtual port failing to login after chip reset.
[SCSI] qla2xxx: Fix vport delete hang when logins are outstanding.
[SCSI] hpsa: Change memset using sizeof(ptr) to sizeof(*ptr)
[SCSI] ipr: Rate limit DMA mapping errors
[SCSI] hpsa: add P2000 to list of shared SAS devices
[SCSI] hpsa: do not attempt PCI power management reset method if we know it won't work.
[SCSI] hpsa: remove superfluous sleeps around reset code
...
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 42 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 49 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 5 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 617 |
5 files changed, 638 insertions, 76 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 3346357031e..efa0255491c 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -522,7 +522,8 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, | |||
522 | desc = "Device Status Change"; | 522 | desc = "Device Status Change"; |
523 | break; | 523 | break; |
524 | case MPI2_EVENT_IR_OPERATION_STATUS: | 524 | case MPI2_EVENT_IR_OPERATION_STATUS: |
525 | desc = "IR Operation Status"; | 525 | if (!ioc->hide_ir_msg) |
526 | desc = "IR Operation Status"; | ||
526 | break; | 527 | break; |
527 | case MPI2_EVENT_SAS_DISCOVERY: | 528 | case MPI2_EVENT_SAS_DISCOVERY: |
528 | { | 529 | { |
@@ -553,16 +554,20 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, | |||
553 | desc = "SAS Enclosure Device Status Change"; | 554 | desc = "SAS Enclosure Device Status Change"; |
554 | break; | 555 | break; |
555 | case MPI2_EVENT_IR_VOLUME: | 556 | case MPI2_EVENT_IR_VOLUME: |
556 | desc = "IR Volume"; | 557 | if (!ioc->hide_ir_msg) |
558 | desc = "IR Volume"; | ||
557 | break; | 559 | break; |
558 | case MPI2_EVENT_IR_PHYSICAL_DISK: | 560 | case MPI2_EVENT_IR_PHYSICAL_DISK: |
559 | desc = "IR Physical Disk"; | 561 | if (!ioc->hide_ir_msg) |
562 | desc = "IR Physical Disk"; | ||
560 | break; | 563 | break; |
561 | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: | 564 | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: |
562 | desc = "IR Configuration Change List"; | 565 | if (!ioc->hide_ir_msg) |
566 | desc = "IR Configuration Change List"; | ||
563 | break; | 567 | break; |
564 | case MPI2_EVENT_LOG_ENTRY_ADDED: | 568 | case MPI2_EVENT_LOG_ENTRY_ADDED: |
565 | desc = "Log Entry Added"; | 569 | if (!ioc->hide_ir_msg) |
570 | desc = "Log Entry Added"; | ||
566 | break; | 571 | break; |
567 | } | 572 | } |
568 | 573 | ||
@@ -616,7 +621,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) | |||
616 | originator_str = "PL"; | 621 | originator_str = "PL"; |
617 | break; | 622 | break; |
618 | case 2: | 623 | case 2: |
619 | originator_str = "IR"; | 624 | if (!ioc->hide_ir_msg) |
625 | originator_str = "IR"; | ||
626 | else | ||
627 | originator_str = "WarpDrive"; | ||
620 | break; | 628 | break; |
621 | } | 629 | } |
622 | 630 | ||
@@ -1508,6 +1516,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
1508 | } | 1516 | } |
1509 | ioc->scsi_lookup[i].cb_idx = 0xFF; | 1517 | ioc->scsi_lookup[i].cb_idx = 0xFF; |
1510 | ioc->scsi_lookup[i].scmd = NULL; | 1518 | ioc->scsi_lookup[i].scmd = NULL; |
1519 | ioc->scsi_lookup[i].direct_io = 0; | ||
1511 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, | 1520 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, |
1512 | &ioc->free_list); | 1521 | &ioc->free_list); |
1513 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); | 1522 | spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); |
@@ -1844,10 +1853,12 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) | |||
1844 | printk("), "); | 1853 | printk("), "); |
1845 | printk("Capabilities=("); | 1854 | printk("Capabilities=("); |
1846 | 1855 | ||
1847 | if (ioc->facts.IOCCapabilities & | 1856 | if (!ioc->hide_ir_msg) { |
1848 | MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { | 1857 | if (ioc->facts.IOCCapabilities & |
1849 | printk("Raid"); | 1858 | MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { |
1850 | i++; | 1859 | printk("Raid"); |
1860 | i++; | ||
1861 | } | ||
1851 | } | 1862 | } |
1852 | 1863 | ||
1853 | if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { | 1864 | if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { |
@@ -3680,6 +3691,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3680 | u32 reply_address; | 3691 | u32 reply_address; |
3681 | u16 smid; | 3692 | u16 smid; |
3682 | struct _tr_list *delayed_tr, *delayed_tr_next; | 3693 | struct _tr_list *delayed_tr, *delayed_tr_next; |
3694 | u8 hide_flag; | ||
3683 | 3695 | ||
3684 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 3696 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3685 | __func__)); | 3697 | __func__)); |
@@ -3706,6 +3718,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3706 | ioc->scsi_lookup[i].cb_idx = 0xFF; | 3718 | ioc->scsi_lookup[i].cb_idx = 0xFF; |
3707 | ioc->scsi_lookup[i].smid = smid; | 3719 | ioc->scsi_lookup[i].smid = smid; |
3708 | ioc->scsi_lookup[i].scmd = NULL; | 3720 | ioc->scsi_lookup[i].scmd = NULL; |
3721 | ioc->scsi_lookup[i].direct_io = 0; | ||
3709 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, | 3722 | list_add_tail(&ioc->scsi_lookup[i].tracker_list, |
3710 | &ioc->free_list); | 3723 | &ioc->free_list); |
3711 | } | 3724 | } |
@@ -3766,6 +3779,15 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
3766 | if (sleep_flag == CAN_SLEEP) | 3779 | if (sleep_flag == CAN_SLEEP) |
3767 | _base_static_config_pages(ioc); | 3780 | _base_static_config_pages(ioc); |
3768 | 3781 | ||
3782 | if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) { | ||
3783 | if (ioc->manu_pg10.OEMIdentifier == 0x80) { | ||
3784 | hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 & | ||
3785 | MFG_PAGE10_HIDE_SSDS_MASK); | ||
3786 | if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK) | ||
3787 | ioc->mfg_pg10_hide_flag = hide_flag; | ||
3788 | } | ||
3789 | } | ||
3790 | |||
3769 | if (ioc->wait_for_port_enable_to_complete) { | 3791 | if (ioc->wait_for_port_enable_to_complete) { |
3770 | if (diag_buffer_enable != 0) | 3792 | if (diag_buffer_enable != 0) |
3771 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | 3793 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 500328245f6..2a3c05f6db8 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -69,11 +69,11 @@ | |||
69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" | 69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" |
70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" | 70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" |
71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" | 71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" |
72 | #define MPT2SAS_DRIVER_VERSION "08.100.00.00" | 72 | #define MPT2SAS_DRIVER_VERSION "08.100.00.01" |
73 | #define MPT2SAS_MAJOR_VERSION 08 | 73 | #define MPT2SAS_MAJOR_VERSION 08 |
74 | #define MPT2SAS_MINOR_VERSION 100 | 74 | #define MPT2SAS_MINOR_VERSION 100 |
75 | #define MPT2SAS_BUILD_VERSION 00 | 75 | #define MPT2SAS_BUILD_VERSION 00 |
76 | #define MPT2SAS_RELEASE_VERSION 00 | 76 | #define MPT2SAS_RELEASE_VERSION 01 |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Set MPT2SAS_SG_DEPTH value based on user input. | 79 | * Set MPT2SAS_SG_DEPTH value based on user input. |
@@ -189,6 +189,16 @@ | |||
189 | #define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046 | 189 | #define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046 |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * WarpDrive Specific Log codes | ||
193 | */ | ||
194 | |||
195 | #define MPT2_WARPDRIVE_LOGENTRY (0x8002) | ||
196 | #define MPT2_WARPDRIVE_LC_SSDT (0x41) | ||
197 | #define MPT2_WARPDRIVE_LC_SSDLW (0x43) | ||
198 | #define MPT2_WARPDRIVE_LC_SSDLF (0x44) | ||
199 | #define MPT2_WARPDRIVE_LC_BRMF (0x4D) | ||
200 | |||
201 | /* | ||
192 | * per target private data | 202 | * per target private data |
193 | */ | 203 | */ |
194 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 | 204 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 |
@@ -199,6 +209,7 @@ | |||
199 | * struct MPT2SAS_TARGET - starget private hostdata | 209 | * struct MPT2SAS_TARGET - starget private hostdata |
200 | * @starget: starget object | 210 | * @starget: starget object |
201 | * @sas_address: target sas address | 211 | * @sas_address: target sas address |
212 | * @raid_device: raid_device pointer to access volume data | ||
202 | * @handle: device handle | 213 | * @handle: device handle |
203 | * @num_luns: number luns | 214 | * @num_luns: number luns |
204 | * @flags: MPT_TARGET_FLAGS_XXX flags | 215 | * @flags: MPT_TARGET_FLAGS_XXX flags |
@@ -208,6 +219,7 @@ | |||
208 | struct MPT2SAS_TARGET { | 219 | struct MPT2SAS_TARGET { |
209 | struct scsi_target *starget; | 220 | struct scsi_target *starget; |
210 | u64 sas_address; | 221 | u64 sas_address; |
222 | struct _raid_device *raid_device; | ||
211 | u16 handle; | 223 | u16 handle; |
212 | int num_luns; | 224 | int num_luns; |
213 | u32 flags; | 225 | u32 flags; |
@@ -215,6 +227,7 @@ struct MPT2SAS_TARGET { | |||
215 | u8 tm_busy; | 227 | u8 tm_busy; |
216 | }; | 228 | }; |
217 | 229 | ||
230 | |||
218 | /* | 231 | /* |
219 | * per device private data | 232 | * per device private data |
220 | */ | 233 | */ |
@@ -262,6 +275,12 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_10 { | |||
262 | MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10, | 275 | MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10, |
263 | Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t; | 276 | Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t; |
264 | 277 | ||
278 | #define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003) | ||
279 | #define MFG_PAGE10_HIDE_ALL_DISKS (0x00) | ||
280 | #define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01) | ||
281 | #define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02) | ||
282 | |||
283 | |||
265 | struct MPT2SAS_DEVICE { | 284 | struct MPT2SAS_DEVICE { |
266 | struct MPT2SAS_TARGET *sas_target; | 285 | struct MPT2SAS_TARGET *sas_target; |
267 | unsigned int lun; | 286 | unsigned int lun; |
@@ -341,6 +360,7 @@ struct _sas_device { | |||
341 | * @sdev: scsi device struct (volumes are single lun) | 360 | * @sdev: scsi device struct (volumes are single lun) |
342 | * @wwid: unique identifier for the volume | 361 | * @wwid: unique identifier for the volume |
343 | * @handle: device handle | 362 | * @handle: device handle |
363 | * @block_size: Block size of the volume | ||
344 | * @id: target id | 364 | * @id: target id |
345 | * @channel: target channel | 365 | * @channel: target channel |
346 | * @volume_type: the raid level | 366 | * @volume_type: the raid level |
@@ -348,20 +368,33 @@ struct _sas_device { | |||
348 | * @num_pds: number of hidden raid components | 368 | * @num_pds: number of hidden raid components |
349 | * @responding: used in _scsih_raid_device_mark_responding | 369 | * @responding: used in _scsih_raid_device_mark_responding |
350 | * @percent_complete: resync percent complete | 370 | * @percent_complete: resync percent complete |
371 | * @direct_io_enabled: Whether direct io to PDs are allowed or not | ||
372 | * @stripe_exponent: X where 2powX is the stripe sz in blocks | ||
373 | * @max_lba: Maximum number of LBA in the volume | ||
374 | * @stripe_sz: Stripe Size of the volume | ||
375 | * @device_info: Device info of the volume member disk | ||
376 | * @pd_handle: Array of handles of the physical drives for direct I/O in le16 | ||
351 | */ | 377 | */ |
378 | #define MPT_MAX_WARPDRIVE_PDS 8 | ||
352 | struct _raid_device { | 379 | struct _raid_device { |
353 | struct list_head list; | 380 | struct list_head list; |
354 | struct scsi_target *starget; | 381 | struct scsi_target *starget; |
355 | struct scsi_device *sdev; | 382 | struct scsi_device *sdev; |
356 | u64 wwid; | 383 | u64 wwid; |
357 | u16 handle; | 384 | u16 handle; |
385 | u16 block_sz; | ||
358 | int id; | 386 | int id; |
359 | int channel; | 387 | int channel; |
360 | u8 volume_type; | 388 | u8 volume_type; |
361 | u32 device_info; | ||
362 | u8 num_pds; | 389 | u8 num_pds; |
363 | u8 responding; | 390 | u8 responding; |
364 | u8 percent_complete; | 391 | u8 percent_complete; |
392 | u8 direct_io_enabled; | ||
393 | u8 stripe_exponent; | ||
394 | u64 max_lba; | ||
395 | u32 stripe_sz; | ||
396 | u32 device_info; | ||
397 | u16 pd_handle[MPT_MAX_WARPDRIVE_PDS]; | ||
365 | }; | 398 | }; |
366 | 399 | ||
367 | /** | 400 | /** |
@@ -470,6 +503,7 @@ struct chain_tracker { | |||
470 | * @smid: system message id | 503 | * @smid: system message id |
471 | * @scmd: scsi request pointer | 504 | * @scmd: scsi request pointer |
472 | * @cb_idx: callback index | 505 | * @cb_idx: callback index |
506 | * @direct_io: To indicate whether I/O is direct (WARPDRIVE) | ||
473 | * @chain_list: list of chains associated to this IO | 507 | * @chain_list: list of chains associated to this IO |
474 | * @tracker_list: list of free request (ioc->free_list) | 508 | * @tracker_list: list of free request (ioc->free_list) |
475 | */ | 509 | */ |
@@ -477,14 +511,14 @@ struct scsiio_tracker { | |||
477 | u16 smid; | 511 | u16 smid; |
478 | struct scsi_cmnd *scmd; | 512 | struct scsi_cmnd *scmd; |
479 | u8 cb_idx; | 513 | u8 cb_idx; |
514 | u8 direct_io; | ||
480 | struct list_head chain_list; | 515 | struct list_head chain_list; |
481 | struct list_head tracker_list; | 516 | struct list_head tracker_list; |
482 | }; | 517 | }; |
483 | 518 | ||
484 | /** | 519 | /** |
485 | * struct request_tracker - misc mf request tracker | 520 | * struct request_tracker - firmware request tracker |
486 | * @smid: system message id | 521 | * @smid: system message id |
487 | * @scmd: scsi request pointer | ||
488 | * @cb_idx: callback index | 522 | * @cb_idx: callback index |
489 | * @tracker_list: list of free request (ioc->free_list) | 523 | * @tracker_list: list of free request (ioc->free_list) |
490 | */ | 524 | */ |
@@ -832,6 +866,11 @@ struct MPT2SAS_ADAPTER { | |||
832 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; | 866 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; |
833 | u32 ring_buffer_offset; | 867 | u32 ring_buffer_offset; |
834 | u32 ring_buffer_sz; | 868 | u32 ring_buffer_sz; |
869 | u8 is_warpdrive; | ||
870 | u8 hide_ir_msg; | ||
871 | u8 mfg_pg10_hide_flag; | ||
872 | u8 hide_drives; | ||
873 | |||
835 | }; | 874 | }; |
836 | 875 | ||
837 | typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 876 | typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index d72f1f2b139..437c2d94c45 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c | |||
@@ -1041,7 +1041,10 @@ _ctl_getiocinfo(void __user *arg) | |||
1041 | __func__)); | 1041 | __func__)); |
1042 | 1042 | ||
1043 | memset(&karg, 0 , sizeof(karg)); | 1043 | memset(&karg, 0 , sizeof(karg)); |
1044 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; | 1044 | if (ioc->is_warpdrive) |
1045 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200; | ||
1046 | else | ||
1047 | karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; | ||
1045 | if (ioc->pfacts) | 1048 | if (ioc->pfacts) |
1046 | karg.port_number = ioc->pfacts[0].PortNumber; | 1049 | karg.port_number = ioc->pfacts[0].PortNumber; |
1047 | pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); | 1050 | pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h index 69916e46e04..11ff1d5fb8f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h | |||
@@ -133,6 +133,7 @@ struct mpt2_ioctl_pci_info { | |||
133 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) | 133 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) |
134 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) | 134 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) |
135 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) | 135 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) |
136 | #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) | ||
136 | #define MPT2_IOCTL_VERSION_LENGTH (32) | 137 | #define MPT2_IOCTL_VERSION_LENGTH (32) |
137 | 138 | ||
138 | /** | 139 | /** |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index d2064a0533a..f12e02358d6 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -233,6 +233,9 @@ static struct pci_device_id scsih_pci_table[] = { | |||
233 | PCI_ANY_ID, PCI_ANY_ID }, | 233 | PCI_ANY_ID, PCI_ANY_ID }, |
234 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, | 234 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, |
235 | PCI_ANY_ID, PCI_ANY_ID }, | 235 | PCI_ANY_ID, PCI_ANY_ID }, |
236 | /* SSS6200 */ | ||
237 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200, | ||
238 | PCI_ANY_ID, PCI_ANY_ID }, | ||
236 | {0} /* Terminating entry */ | 239 | {0} /* Terminating entry */ |
237 | }; | 240 | }; |
238 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); | 241 | MODULE_DEVICE_TABLE(pci, scsih_pci_table); |
@@ -1256,6 +1259,7 @@ _scsih_target_alloc(struct scsi_target *starget) | |||
1256 | sas_target_priv_data->handle = raid_device->handle; | 1259 | sas_target_priv_data->handle = raid_device->handle; |
1257 | sas_target_priv_data->sas_address = raid_device->wwid; | 1260 | sas_target_priv_data->sas_address = raid_device->wwid; |
1258 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; | 1261 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; |
1262 | sas_target_priv_data->raid_device = raid_device; | ||
1259 | raid_device->starget = starget; | 1263 | raid_device->starget = starget; |
1260 | } | 1264 | } |
1261 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1265 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
@@ -1455,7 +1459,10 @@ static int | |||
1455 | _scsih_is_raid(struct device *dev) | 1459 | _scsih_is_raid(struct device *dev) |
1456 | { | 1460 | { |
1457 | struct scsi_device *sdev = to_scsi_device(dev); | 1461 | struct scsi_device *sdev = to_scsi_device(dev); |
1462 | struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host); | ||
1458 | 1463 | ||
1464 | if (ioc->is_warpdrive) | ||
1465 | return 0; | ||
1459 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; | 1466 | return (sdev->channel == RAID_CHANNEL) ? 1 : 0; |
1460 | } | 1467 | } |
1461 | 1468 | ||
@@ -1480,7 +1487,7 @@ _scsih_get_resync(struct device *dev) | |||
1480 | sdev->channel); | 1487 | sdev->channel); |
1481 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1488 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1482 | 1489 | ||
1483 | if (!raid_device) | 1490 | if (!raid_device || ioc->is_warpdrive) |
1484 | goto out; | 1491 | goto out; |
1485 | 1492 | ||
1486 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, | 1493 | if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, |
@@ -1640,6 +1647,212 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, | |||
1640 | 1647 | ||
1641 | kfree(vol_pg0); | 1648 | kfree(vol_pg0); |
1642 | } | 1649 | } |
1650 | /** | ||
1651 | * _scsih_disable_ddio - Disable direct I/O for all the volumes | ||
1652 | * @ioc: per adapter object | ||
1653 | */ | ||
1654 | static void | ||
1655 | _scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc) | ||
1656 | { | ||
1657 | Mpi2RaidVolPage1_t vol_pg1; | ||
1658 | Mpi2ConfigReply_t mpi_reply; | ||
1659 | struct _raid_device *raid_device; | ||
1660 | u16 handle; | ||
1661 | u16 ioc_status; | ||
1662 | |||
1663 | handle = 0xFFFF; | ||
1664 | while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, | ||
1665 | &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { | ||
1666 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1667 | MPI2_IOCSTATUS_MASK; | ||
1668 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | ||
1669 | break; | ||
1670 | handle = le16_to_cpu(vol_pg1.DevHandle); | ||
1671 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | ||
1672 | if (raid_device) | ||
1673 | raid_device->direct_io_enabled = 0; | ||
1674 | } | ||
1675 | return; | ||
1676 | } | ||
1677 | |||
1678 | |||
1679 | /** | ||
1680 | * _scsih_get_num_volumes - Get number of volumes in the ioc | ||
1681 | * @ioc: per adapter object | ||
1682 | */ | ||
1683 | static u8 | ||
1684 | _scsih_get_num_volumes(struct MPT2SAS_ADAPTER *ioc) | ||
1685 | { | ||
1686 | Mpi2RaidVolPage1_t vol_pg1; | ||
1687 | Mpi2ConfigReply_t mpi_reply; | ||
1688 | u16 handle; | ||
1689 | u8 vol_cnt = 0; | ||
1690 | u16 ioc_status; | ||
1691 | |||
1692 | handle = 0xFFFF; | ||
1693 | while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, | ||
1694 | &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { | ||
1695 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1696 | MPI2_IOCSTATUS_MASK; | ||
1697 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | ||
1698 | break; | ||
1699 | vol_cnt++; | ||
1700 | handle = le16_to_cpu(vol_pg1.DevHandle); | ||
1701 | } | ||
1702 | return vol_cnt; | ||
1703 | } | ||
1704 | |||
1705 | |||
1706 | /** | ||
1707 | * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O. | ||
1708 | * @ioc: per adapter object | ||
1709 | * @raid_device: the raid_device object | ||
1710 | */ | ||
1711 | static void | ||
1712 | _scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc, | ||
1713 | struct _raid_device *raid_device) | ||
1714 | { | ||
1715 | Mpi2RaidVolPage0_t *vol_pg0; | ||
1716 | Mpi2RaidPhysDiskPage0_t pd_pg0; | ||
1717 | Mpi2ConfigReply_t mpi_reply; | ||
1718 | u16 sz; | ||
1719 | u8 num_pds, count; | ||
1720 | u64 mb = 1024 * 1024; | ||
1721 | u64 tb_2 = 2 * mb * mb; | ||
1722 | u64 capacity; | ||
1723 | u32 stripe_sz; | ||
1724 | u8 i, stripe_exp; | ||
1725 | |||
1726 | if (!ioc->is_warpdrive) | ||
1727 | return; | ||
1728 | |||
1729 | if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) { | ||
1730 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1731 | "globally as drives are exposed\n", ioc->name); | ||
1732 | return; | ||
1733 | } | ||
1734 | if (_scsih_get_num_volumes(ioc) > 1) { | ||
1735 | _scsih_disable_ddio(ioc); | ||
1736 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1737 | "globally as number of drives > 1\n", ioc->name); | ||
1738 | return; | ||
1739 | } | ||
1740 | if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, | ||
1741 | &num_pds)) || !num_pds) { | ||
1742 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1743 | "Failure in computing number of drives\n", ioc->name); | ||
1744 | return; | ||
1745 | } | ||
1746 | |||
1747 | sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds * | ||
1748 | sizeof(Mpi2RaidVol0PhysDisk_t)); | ||
1749 | vol_pg0 = kzalloc(sz, GFP_KERNEL); | ||
1750 | if (!vol_pg0) { | ||
1751 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1752 | "Memory allocation failure for RVPG0\n", ioc->name); | ||
1753 | return; | ||
1754 | } | ||
1755 | |||
1756 | if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, | ||
1757 | MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { | ||
1758 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1759 | "Failure in retrieving RVPG0\n", ioc->name); | ||
1760 | kfree(vol_pg0); | ||
1761 | return; | ||
1762 | } | ||
1763 | |||
1764 | /* | ||
1765 | * WARPDRIVE:If number of physical disks in a volume exceeds the max pds | ||
1766 | * assumed for WARPDRIVE, disable direct I/O | ||
1767 | */ | ||
1768 | if (num_pds > MPT_MAX_WARPDRIVE_PDS) { | ||
1769 | printk(MPT2SAS_WARN_FMT "WarpDrive : Direct IO is disabled " | ||
1770 | "for the drive with handle(0x%04x): num_mem=%d, " | ||
1771 | "max_mem_allowed=%d\n", ioc->name, raid_device->handle, | ||
1772 | num_pds, MPT_MAX_WARPDRIVE_PDS); | ||
1773 | kfree(vol_pg0); | ||
1774 | return; | ||
1775 | } | ||
1776 | for (count = 0; count < num_pds; count++) { | ||
1777 | if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, | ||
1778 | &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, | ||
1779 | vol_pg0->PhysDisk[count].PhysDiskNum) || | ||
1780 | pd_pg0.DevHandle == MPT2SAS_INVALID_DEVICE_HANDLE) { | ||
1781 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is " | ||
1782 | "disabled for the drive with handle(0x%04x) member" | ||
1783 | "handle retrieval failed for member number=%d\n", | ||
1784 | ioc->name, raid_device->handle, | ||
1785 | vol_pg0->PhysDisk[count].PhysDiskNum); | ||
1786 | goto out_error; | ||
1787 | } | ||
1788 | raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle); | ||
1789 | } | ||
1790 | |||
1791 | /* | ||
1792 | * Assumption for WD: Direct I/O is not supported if the volume is | ||
1793 | * not RAID0, if the stripe size is not 64KB, if the block size is | ||
1794 | * not 512 and if the volume size is >2TB | ||
1795 | */ | ||
1796 | if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0 || | ||
1797 | le16_to_cpu(vol_pg0->BlockSize) != 512) { | ||
1798 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1799 | "for the drive with handle(0x%04x): type=%d, " | ||
1800 | "s_sz=%uK, blk_size=%u\n", ioc->name, | ||
1801 | raid_device->handle, raid_device->volume_type, | ||
1802 | le32_to_cpu(vol_pg0->StripeSize)/2, | ||
1803 | le16_to_cpu(vol_pg0->BlockSize)); | ||
1804 | goto out_error; | ||
1805 | } | ||
1806 | |||
1807 | capacity = (u64) le16_to_cpu(vol_pg0->BlockSize) * | ||
1808 | (le64_to_cpu(vol_pg0->MaxLBA) + 1); | ||
1809 | |||
1810 | if (capacity > tb_2) { | ||
1811 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1812 | "for the drive with handle(0x%04x) since drive sz > 2TB\n", | ||
1813 | ioc->name, raid_device->handle); | ||
1814 | goto out_error; | ||
1815 | } | ||
1816 | |||
1817 | stripe_sz = le32_to_cpu(vol_pg0->StripeSize); | ||
1818 | stripe_exp = 0; | ||
1819 | for (i = 0; i < 32; i++) { | ||
1820 | if (stripe_sz & 1) | ||
1821 | break; | ||
1822 | stripe_exp++; | ||
1823 | stripe_sz >>= 1; | ||
1824 | } | ||
1825 | if (i == 32) { | ||
1826 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " | ||
1827 | "for the drive with handle(0x%04x) invalid stripe sz %uK\n", | ||
1828 | ioc->name, raid_device->handle, | ||
1829 | le32_to_cpu(vol_pg0->StripeSize)/2); | ||
1830 | goto out_error; | ||
1831 | } | ||
1832 | raid_device->stripe_exponent = stripe_exp; | ||
1833 | raid_device->direct_io_enabled = 1; | ||
1834 | |||
1835 | printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive" | ||
1836 | " with handle(0x%04x)\n", ioc->name, raid_device->handle); | ||
1837 | /* | ||
1838 | * WARPDRIVE: Though the following fields are not used for direct IO, | ||
1839 | * stored for future purpose: | ||
1840 | */ | ||
1841 | raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA); | ||
1842 | raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize); | ||
1843 | raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize); | ||
1844 | |||
1845 | |||
1846 | kfree(vol_pg0); | ||
1847 | return; | ||
1848 | |||
1849 | out_error: | ||
1850 | raid_device->direct_io_enabled = 0; | ||
1851 | for (count = 0; count < num_pds; count++) | ||
1852 | raid_device->pd_handle[count] = 0; | ||
1853 | kfree(vol_pg0); | ||
1854 | return; | ||
1855 | } | ||
1643 | 1856 | ||
1644 | /** | 1857 | /** |
1645 | * _scsih_enable_tlr - setting TLR flags | 1858 | * _scsih_enable_tlr - setting TLR flags |
@@ -1710,6 +1923,11 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1710 | 1923 | ||
1711 | _scsih_get_volume_capabilities(ioc, raid_device); | 1924 | _scsih_get_volume_capabilities(ioc, raid_device); |
1712 | 1925 | ||
1926 | /* | ||
1927 | * WARPDRIVE: Initialize the required data for Direct IO | ||
1928 | */ | ||
1929 | _scsih_init_warpdrive_properties(ioc, raid_device); | ||
1930 | |||
1713 | /* RAID Queue Depth Support | 1931 | /* RAID Queue Depth Support |
1714 | * IS volume = underlying qdepth of drive type, either | 1932 | * IS volume = underlying qdepth of drive type, either |
1715 | * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH | 1933 | * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH |
@@ -1757,14 +1975,16 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1757 | break; | 1975 | break; |
1758 | } | 1976 | } |
1759 | 1977 | ||
1760 | sdev_printk(KERN_INFO, sdev, "%s: " | 1978 | if (!ioc->hide_ir_msg) |
1761 | "handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n", | 1979 | sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " |
1762 | r_level, raid_device->handle, | 1980 | "wwid(0x%016llx), pd_count(%d), type(%s)\n", |
1763 | (unsigned long long)raid_device->wwid, | 1981 | r_level, raid_device->handle, |
1764 | raid_device->num_pds, ds); | 1982 | (unsigned long long)raid_device->wwid, |
1983 | raid_device->num_pds, ds); | ||
1765 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); | 1984 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); |
1766 | /* raid transport support */ | 1985 | /* raid transport support */ |
1767 | _scsih_set_level(sdev, raid_device); | 1986 | if (!ioc->is_warpdrive) |
1987 | _scsih_set_level(sdev, raid_device); | ||
1768 | return 0; | 1988 | return 0; |
1769 | } | 1989 | } |
1770 | 1990 | ||
@@ -2133,8 +2353,7 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint channel, | |||
2133 | switch (type) { | 2353 | switch (type) { |
2134 | case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: | 2354 | case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: |
2135 | scmd_lookup = _scsih_scsi_lookup_get(ioc, smid_task); | 2355 | scmd_lookup = _scsih_scsi_lookup_get(ioc, smid_task); |
2136 | if (scmd_lookup && (scmd_lookup->serial_number == | 2356 | if (scmd_lookup) |
2137 | scmd->serial_number)) | ||
2138 | rc = FAILED; | 2357 | rc = FAILED; |
2139 | else | 2358 | else |
2140 | rc = SUCCESS; | 2359 | rc = SUCCESS; |
@@ -2182,16 +2401,20 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2182 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; | 2401 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; |
2183 | struct _sas_device *sas_device = NULL; | 2402 | struct _sas_device *sas_device = NULL; |
2184 | unsigned long flags; | 2403 | unsigned long flags; |
2404 | char *device_str = NULL; | ||
2185 | 2405 | ||
2186 | if (!priv_target) | 2406 | if (!priv_target) |
2187 | return; | 2407 | return; |
2408 | if (ioc->hide_ir_msg) | ||
2409 | device_str = "WarpDrive"; | ||
2410 | else | ||
2411 | device_str = "volume"; | ||
2188 | 2412 | ||
2189 | scsi_print_command(scmd); | 2413 | scsi_print_command(scmd); |
2190 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { | 2414 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { |
2191 | starget_printk(KERN_INFO, starget, "volume handle(0x%04x), " | 2415 | starget_printk(KERN_INFO, starget, "%s handle(0x%04x), " |
2192 | "volume wwid(0x%016llx)\n", | 2416 | "%s wwid(0x%016llx)\n", device_str, priv_target->handle, |
2193 | priv_target->handle, | 2417 | device_str, (unsigned long long)priv_target->sas_address); |
2194 | (unsigned long long)priv_target->sas_address); | ||
2195 | } else { | 2418 | } else { |
2196 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2419 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2197 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 2420 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, |
@@ -3130,6 +3353,9 @@ _scsih_check_ir_config_unhide_events(struct MPT2SAS_ADAPTER *ioc, | |||
3130 | a = 0; | 3353 | a = 0; |
3131 | b = 0; | 3354 | b = 0; |
3132 | 3355 | ||
3356 | if (ioc->is_warpdrive) | ||
3357 | return; | ||
3358 | |||
3133 | /* Volume Resets for Deleted or Removed */ | 3359 | /* Volume Resets for Deleted or Removed */ |
3134 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | 3360 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; |
3135 | for (i = 0; i < event_data->NumElements; i++, element++) { | 3361 | for (i = 0; i < event_data->NumElements; i++, element++) { |
@@ -3347,6 +3573,105 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) | |||
3347 | } | 3573 | } |
3348 | 3574 | ||
3349 | /** | 3575 | /** |
3576 | * _scsih_scsi_direct_io_get - returns direct io flag | ||
3577 | * @ioc: per adapter object | ||
3578 | * @smid: system request message index | ||
3579 | * | ||
3580 | * Returns the smid stored scmd pointer. | ||
3581 | */ | ||
3582 | static inline u8 | ||
3583 | _scsih_scsi_direct_io_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) | ||
3584 | { | ||
3585 | return ioc->scsi_lookup[smid - 1].direct_io; | ||
3586 | } | ||
3587 | |||
3588 | /** | ||
3589 | * _scsih_scsi_direct_io_set - sets direct io flag | ||
3590 | * @ioc: per adapter object | ||
3591 | * @smid: system request message index | ||
3592 | * @direct_io: Zero or non-zero value to set in the direct_io flag | ||
3593 | * | ||
3594 | * Returns Nothing. | ||
3595 | */ | ||
3596 | static inline void | ||
3597 | _scsih_scsi_direct_io_set(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 direct_io) | ||
3598 | { | ||
3599 | ioc->scsi_lookup[smid - 1].direct_io = direct_io; | ||
3600 | } | ||
3601 | |||
3602 | |||
3603 | /** | ||
3604 | * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O | ||
3605 | * @ioc: per adapter object | ||
3606 | * @scmd: pointer to scsi command object | ||
3607 | * @raid_device: pointer to raid device data structure | ||
3608 | * @mpi_request: pointer to the SCSI_IO reqest message frame | ||
3609 | * @smid: system request message index | ||
3610 | * | ||
3611 | * Returns nothing | ||
3612 | */ | ||
3613 | static void | ||
3614 | _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | ||
3615 | struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, | ||
3616 | u16 smid) | ||
3617 | { | ||
3618 | u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size; | ||
3619 | u32 stripe_sz, stripe_exp; | ||
3620 | u8 num_pds, *cdb_ptr, *tmp_ptr, *lba_ptr1, *lba_ptr2; | ||
3621 | u8 cdb0 = scmd->cmnd[0]; | ||
3622 | |||
3623 | /* | ||
3624 | * Try Direct I/O to RAID memeber disks | ||
3625 | */ | ||
3626 | if (cdb0 == READ_16 || cdb0 == READ_10 || | ||
3627 | cdb0 == WRITE_16 || cdb0 == WRITE_10) { | ||
3628 | cdb_ptr = mpi_request->CDB.CDB32; | ||
3629 | |||
3630 | if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4] | ||
3631 | | cdb_ptr[5])) { | ||
3632 | io_size = scsi_bufflen(scmd) >> 9; | ||
3633 | /* get virtual lba */ | ||
3634 | lba_ptr1 = lba_ptr2 = (cdb0 < READ_16) ? &cdb_ptr[2] : | ||
3635 | &cdb_ptr[6]; | ||
3636 | tmp_ptr = (u8 *)&v_lba + 3; | ||
3637 | *tmp_ptr-- = *lba_ptr1++; | ||
3638 | *tmp_ptr-- = *lba_ptr1++; | ||
3639 | *tmp_ptr-- = *lba_ptr1++; | ||
3640 | *tmp_ptr = *lba_ptr1; | ||
3641 | |||
3642 | if (((u64)v_lba + (u64)io_size - 1) <= | ||
3643 | (u32)raid_device->max_lba) { | ||
3644 | stripe_sz = raid_device->stripe_sz; | ||
3645 | stripe_exp = raid_device->stripe_exponent; | ||
3646 | stripe_off = v_lba & (stripe_sz - 1); | ||
3647 | |||
3648 | /* Check whether IO falls within a stripe */ | ||
3649 | if ((stripe_off + io_size) <= stripe_sz) { | ||
3650 | num_pds = raid_device->num_pds; | ||
3651 | p_lba = v_lba >> stripe_exp; | ||
3652 | stripe_unit = p_lba / num_pds; | ||
3653 | column = p_lba % num_pds; | ||
3654 | p_lba = (stripe_unit << stripe_exp) + | ||
3655 | stripe_off; | ||
3656 | mpi_request->DevHandle = | ||
3657 | cpu_to_le16(raid_device-> | ||
3658 | pd_handle[column]); | ||
3659 | tmp_ptr = (u8 *)&p_lba + 3; | ||
3660 | *lba_ptr2++ = *tmp_ptr--; | ||
3661 | *lba_ptr2++ = *tmp_ptr--; | ||
3662 | *lba_ptr2++ = *tmp_ptr--; | ||
3663 | *lba_ptr2 = *tmp_ptr; | ||
3664 | /* | ||
3665 | * WD: To indicate this I/O is directI/O | ||
3666 | */ | ||
3667 | _scsih_scsi_direct_io_set(ioc, smid, 1); | ||
3668 | } | ||
3669 | } | ||
3670 | } | ||
3671 | } | ||
3672 | } | ||
3673 | |||
3674 | /** | ||
3350 | * _scsih_qcmd - main scsi request entry point | 3675 | * _scsih_qcmd - main scsi request entry point |
3351 | * @scmd: pointer to scsi command object | 3676 | * @scmd: pointer to scsi command object |
3352 | * @done: function pointer to be invoked on completion | 3677 | * @done: function pointer to be invoked on completion |
@@ -3363,6 +3688,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
3363 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 3688 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
3364 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 3689 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
3365 | struct MPT2SAS_TARGET *sas_target_priv_data; | 3690 | struct MPT2SAS_TARGET *sas_target_priv_data; |
3691 | struct _raid_device *raid_device; | ||
3366 | Mpi2SCSIIORequest_t *mpi_request; | 3692 | Mpi2SCSIIORequest_t *mpi_request; |
3367 | u32 mpi_control; | 3693 | u32 mpi_control; |
3368 | u16 smid; | 3694 | u16 smid; |
@@ -3424,8 +3750,10 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
3424 | 3750 | ||
3425 | } else | 3751 | } else |
3426 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 3752 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
3427 | /* Make sure Device is not raid volume */ | 3753 | /* Make sure Device is not raid volume. |
3428 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && | 3754 | * We do not expose raid functionality to upper layer for warpdrive. |
3755 | */ | ||
3756 | if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) && | ||
3429 | sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32) | 3757 | sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32) |
3430 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; | 3758 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; |
3431 | 3759 | ||
@@ -3473,9 +3801,14 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
3473 | } | 3801 | } |
3474 | } | 3802 | } |
3475 | 3803 | ||
3804 | raid_device = sas_target_priv_data->raid_device; | ||
3805 | if (raid_device && raid_device->direct_io_enabled) | ||
3806 | _scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request, | ||
3807 | smid); | ||
3808 | |||
3476 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) | 3809 | if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) |
3477 | mpt2sas_base_put_smid_scsi_io(ioc, smid, | 3810 | mpt2sas_base_put_smid_scsi_io(ioc, smid, |
3478 | sas_device_priv_data->sas_target->handle); | 3811 | le16_to_cpu(mpi_request->DevHandle)); |
3479 | else | 3812 | else |
3480 | mpt2sas_base_put_smid_default(ioc, smid); | 3813 | mpt2sas_base_put_smid_default(ioc, smid); |
3481 | return 0; | 3814 | return 0; |
@@ -3540,10 +3873,16 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3540 | unsigned long flags; | 3873 | unsigned long flags; |
3541 | struct scsi_target *starget = scmd->device->sdev_target; | 3874 | struct scsi_target *starget = scmd->device->sdev_target; |
3542 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; | 3875 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; |
3876 | char *device_str = NULL; | ||
3543 | 3877 | ||
3544 | if (!priv_target) | 3878 | if (!priv_target) |
3545 | return; | 3879 | return; |
3546 | 3880 | ||
3881 | if (ioc->hide_ir_msg) | ||
3882 | device_str = "WarpDrive"; | ||
3883 | else | ||
3884 | device_str = "volume"; | ||
3885 | |||
3547 | if (log_info == 0x31170000) | 3886 | if (log_info == 0x31170000) |
3548 | return; | 3887 | return; |
3549 | 3888 | ||
@@ -3660,8 +3999,8 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3660 | scsi_print_command(scmd); | 3999 | scsi_print_command(scmd); |
3661 | 4000 | ||
3662 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { | 4001 | if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { |
3663 | printk(MPT2SAS_WARN_FMT "\tvolume wwid(0x%016llx)\n", ioc->name, | 4002 | printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name, |
3664 | (unsigned long long)priv_target->sas_address); | 4003 | device_str, (unsigned long long)priv_target->sas_address); |
3665 | } else { | 4004 | } else { |
3666 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4005 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
3667 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 4006 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, |
@@ -3840,6 +4179,20 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3840 | scmd->result = DID_NO_CONNECT << 16; | 4179 | scmd->result = DID_NO_CONNECT << 16; |
3841 | goto out; | 4180 | goto out; |
3842 | } | 4181 | } |
4182 | /* | ||
4183 | * WARPDRIVE: If direct_io is set then it is directIO, | ||
4184 | * the failed direct I/O should be redirected to volume | ||
4185 | */ | ||
4186 | if (_scsih_scsi_direct_io_get(ioc, smid)) { | ||
4187 | _scsih_scsi_direct_io_set(ioc, smid, 0); | ||
4188 | memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); | ||
4189 | mpi_request->DevHandle = | ||
4190 | cpu_to_le16(sas_device_priv_data->sas_target->handle); | ||
4191 | mpt2sas_base_put_smid_scsi_io(ioc, smid, | ||
4192 | sas_device_priv_data->sas_target->handle); | ||
4193 | return 0; | ||
4194 | } | ||
4195 | |||
3843 | 4196 | ||
3844 | /* turning off TLR */ | 4197 | /* turning off TLR */ |
3845 | scsi_state = mpi_reply->SCSIState; | 4198 | scsi_state = mpi_reply->SCSIState; |
@@ -3848,7 +4201,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3848 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; | 4201 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; |
3849 | if (!sas_device_priv_data->tlr_snoop_check) { | 4202 | if (!sas_device_priv_data->tlr_snoop_check) { |
3850 | sas_device_priv_data->tlr_snoop_check++; | 4203 | sas_device_priv_data->tlr_snoop_check++; |
3851 | if (!_scsih_is_raid(&scmd->device->sdev_gendev) && | 4204 | /* Make sure Device is not raid volume. |
4205 | * We do not expose raid functionality to upper layer for warpdrive. | ||
4206 | */ | ||
4207 | if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) && | ||
3852 | sas_is_tlr_enabled(scmd->device) && | 4208 | sas_is_tlr_enabled(scmd->device) && |
3853 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { | 4209 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { |
3854 | sas_disable_tlr(scmd->device); | 4210 | sas_disable_tlr(scmd->device); |
@@ -4681,8 +5037,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, | |||
4681 | 5037 | ||
4682 | _scsih_ublock_io_device(ioc, sas_device_backup.handle); | 5038 | _scsih_ublock_io_device(ioc, sas_device_backup.handle); |
4683 | 5039 | ||
4684 | mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address, | 5040 | if (!ioc->hide_drives) |
4685 | sas_device_backup.sas_address_parent); | 5041 | mpt2sas_transport_port_remove(ioc, |
5042 | sas_device_backup.sas_address, | ||
5043 | sas_device_backup.sas_address_parent); | ||
4686 | 5044 | ||
4687 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" | 5045 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" |
4688 | "(0x%016llx)\n", ioc->name, sas_device_backup.handle, | 5046 | "(0x%016llx)\n", ioc->name, sas_device_backup.handle, |
@@ -5413,6 +5771,7 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc, | |||
5413 | &sas_device->volume_wwid); | 5771 | &sas_device->volume_wwid); |
5414 | set_bit(handle, ioc->pd_handles); | 5772 | set_bit(handle, ioc->pd_handles); |
5415 | _scsih_reprobe_target(sas_device->starget, 1); | 5773 | _scsih_reprobe_target(sas_device->starget, 1); |
5774 | |||
5416 | } | 5775 | } |
5417 | 5776 | ||
5418 | /** | 5777 | /** |
@@ -5591,7 +5950,8 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
5591 | Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data; | 5950 | Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data; |
5592 | 5951 | ||
5593 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 5952 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
5594 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 5953 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
5954 | && !ioc->hide_ir_msg) | ||
5595 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); | 5955 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); |
5596 | 5956 | ||
5597 | #endif | 5957 | #endif |
@@ -5614,16 +5974,20 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
5614 | le16_to_cpu(element->VolDevHandle)); | 5974 | le16_to_cpu(element->VolDevHandle)); |
5615 | break; | 5975 | break; |
5616 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: | 5976 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: |
5617 | _scsih_sas_pd_hide(ioc, element); | 5977 | if (!ioc->is_warpdrive) |
5978 | _scsih_sas_pd_hide(ioc, element); | ||
5618 | break; | 5979 | break; |
5619 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: | 5980 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: |
5620 | _scsih_sas_pd_expose(ioc, element); | 5981 | if (!ioc->is_warpdrive) |
5982 | _scsih_sas_pd_expose(ioc, element); | ||
5621 | break; | 5983 | break; |
5622 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: | 5984 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: |
5623 | _scsih_sas_pd_add(ioc, element); | 5985 | if (!ioc->is_warpdrive) |
5986 | _scsih_sas_pd_add(ioc, element); | ||
5624 | break; | 5987 | break; |
5625 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: | 5988 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: |
5626 | _scsih_sas_pd_delete(ioc, element); | 5989 | if (!ioc->is_warpdrive) |
5990 | _scsih_sas_pd_delete(ioc, element); | ||
5627 | break; | 5991 | break; |
5628 | } | 5992 | } |
5629 | } | 5993 | } |
@@ -5654,9 +6018,10 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, | |||
5654 | 6018 | ||
5655 | handle = le16_to_cpu(event_data->VolDevHandle); | 6019 | handle = le16_to_cpu(event_data->VolDevHandle); |
5656 | state = le32_to_cpu(event_data->NewValue); | 6020 | state = le32_to_cpu(event_data->NewValue); |
5657 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " | 6021 | if (!ioc->hide_ir_msg) |
5658 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, | 6022 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " |
5659 | le32_to_cpu(event_data->PreviousValue), state)); | 6023 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, |
6024 | le32_to_cpu(event_data->PreviousValue), state)); | ||
5660 | 6025 | ||
5661 | switch (state) { | 6026 | switch (state) { |
5662 | case MPI2_RAID_VOL_STATE_MISSING: | 6027 | case MPI2_RAID_VOL_STATE_MISSING: |
@@ -5736,9 +6101,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
5736 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); | 6101 | handle = le16_to_cpu(event_data->PhysDiskDevHandle); |
5737 | state = le32_to_cpu(event_data->NewValue); | 6102 | state = le32_to_cpu(event_data->NewValue); |
5738 | 6103 | ||
5739 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " | 6104 | if (!ioc->hide_ir_msg) |
5740 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, | 6105 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " |
5741 | le32_to_cpu(event_data->PreviousValue), state)); | 6106 | "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, |
6107 | le32_to_cpu(event_data->PreviousValue), state)); | ||
5742 | 6108 | ||
5743 | switch (state) { | 6109 | switch (state) { |
5744 | case MPI2_RAID_PD_STATE_ONLINE: | 6110 | case MPI2_RAID_PD_STATE_ONLINE: |
@@ -5747,7 +6113,8 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
5747 | case MPI2_RAID_PD_STATE_OPTIMAL: | 6113 | case MPI2_RAID_PD_STATE_OPTIMAL: |
5748 | case MPI2_RAID_PD_STATE_HOT_SPARE: | 6114 | case MPI2_RAID_PD_STATE_HOT_SPARE: |
5749 | 6115 | ||
5750 | set_bit(handle, ioc->pd_handles); | 6116 | if (!ioc->is_warpdrive) |
6117 | set_bit(handle, ioc->pd_handles); | ||
5751 | 6118 | ||
5752 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6119 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5753 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6120 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
@@ -5851,7 +6218,8 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, | |||
5851 | u16 handle; | 6218 | u16 handle; |
5852 | 6219 | ||
5853 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 6220 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
5854 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 6221 | if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
6222 | && !ioc->hide_ir_msg) | ||
5855 | _scsih_sas_ir_operation_status_event_debug(ioc, | 6223 | _scsih_sas_ir_operation_status_event_debug(ioc, |
5856 | event_data); | 6224 | event_data); |
5857 | #endif | 6225 | #endif |
@@ -5910,7 +6278,7 @@ static void | |||
5910 | _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | 6278 | _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, |
5911 | u16 slot, u16 handle) | 6279 | u16 slot, u16 handle) |
5912 | { | 6280 | { |
5913 | struct MPT2SAS_TARGET *sas_target_priv_data; | 6281 | struct MPT2SAS_TARGET *sas_target_priv_data = NULL; |
5914 | struct scsi_target *starget; | 6282 | struct scsi_target *starget; |
5915 | struct _sas_device *sas_device; | 6283 | struct _sas_device *sas_device; |
5916 | unsigned long flags; | 6284 | unsigned long flags; |
@@ -5918,7 +6286,7 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
5918 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6286 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5919 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) { | 6287 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) { |
5920 | if (sas_device->sas_address == sas_address && | 6288 | if (sas_device->sas_address == sas_address && |
5921 | sas_device->slot == slot && sas_device->starget) { | 6289 | sas_device->slot == slot) { |
5922 | sas_device->responding = 1; | 6290 | sas_device->responding = 1; |
5923 | starget = sas_device->starget; | 6291 | starget = sas_device->starget; |
5924 | if (starget && starget->hostdata) { | 6292 | if (starget && starget->hostdata) { |
@@ -5927,13 +6295,15 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
5927 | sas_target_priv_data->deleted = 0; | 6295 | sas_target_priv_data->deleted = 0; |
5928 | } else | 6296 | } else |
5929 | sas_target_priv_data = NULL; | 6297 | sas_target_priv_data = NULL; |
5930 | starget_printk(KERN_INFO, sas_device->starget, | 6298 | if (starget) |
5931 | "handle(0x%04x), sas_addr(0x%016llx), enclosure " | 6299 | starget_printk(KERN_INFO, starget, |
5932 | "logical id(0x%016llx), slot(%d)\n", handle, | 6300 | "handle(0x%04x), sas_addr(0x%016llx), " |
5933 | (unsigned long long)sas_device->sas_address, | 6301 | "enclosure logical id(0x%016llx), " |
5934 | (unsigned long long) | 6302 | "slot(%d)\n", handle, |
5935 | sas_device->enclosure_logical_id, | 6303 | (unsigned long long)sas_device->sas_address, |
5936 | sas_device->slot); | 6304 | (unsigned long long) |
6305 | sas_device->enclosure_logical_id, | ||
6306 | sas_device->slot); | ||
5937 | if (sas_device->handle == handle) | 6307 | if (sas_device->handle == handle) |
5938 | goto out; | 6308 | goto out; |
5939 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", | 6309 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", |
@@ -6025,6 +6395,12 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid, | |||
6025 | starget_printk(KERN_INFO, raid_device->starget, | 6395 | starget_printk(KERN_INFO, raid_device->starget, |
6026 | "handle(0x%04x), wwid(0x%016llx)\n", handle, | 6396 | "handle(0x%04x), wwid(0x%016llx)\n", handle, |
6027 | (unsigned long long)raid_device->wwid); | 6397 | (unsigned long long)raid_device->wwid); |
6398 | /* | ||
6399 | * WARPDRIVE: The handles of the PDs might have changed | ||
6400 | * across the host reset so re-initialize the | ||
6401 | * required data for Direct IO | ||
6402 | */ | ||
6403 | _scsih_init_warpdrive_properties(ioc, raid_device); | ||
6028 | if (raid_device->handle == handle) | 6404 | if (raid_device->handle == handle) |
6029 | goto out; | 6405 | goto out; |
6030 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", | 6406 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", |
@@ -6086,18 +6462,20 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc) | |||
6086 | } | 6462 | } |
6087 | 6463 | ||
6088 | /* refresh the pd_handles */ | 6464 | /* refresh the pd_handles */ |
6089 | phys_disk_num = 0xFF; | 6465 | if (!ioc->is_warpdrive) { |
6090 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); | 6466 | phys_disk_num = 0xFF; |
6091 | while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, | 6467 | memset(ioc->pd_handles, 0, ioc->pd_handles_sz); |
6092 | &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, | 6468 | while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, |
6093 | phys_disk_num))) { | 6469 | &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, |
6094 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | 6470 | phys_disk_num))) { |
6095 | MPI2_IOCSTATUS_MASK; | 6471 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & |
6096 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) | 6472 | MPI2_IOCSTATUS_MASK; |
6097 | break; | 6473 | if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) |
6098 | phys_disk_num = pd_pg0.PhysDiskNum; | 6474 | break; |
6099 | handle = le16_to_cpu(pd_pg0.DevHandle); | 6475 | phys_disk_num = pd_pg0.PhysDiskNum; |
6100 | set_bit(handle, ioc->pd_handles); | 6476 | handle = le16_to_cpu(pd_pg0.DevHandle); |
6477 | set_bit(handle, ioc->pd_handles); | ||
6478 | } | ||
6101 | } | 6479 | } |
6102 | } | 6480 | } |
6103 | 6481 | ||
@@ -6243,6 +6621,50 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc) | |||
6243 | } | 6621 | } |
6244 | 6622 | ||
6245 | /** | 6623 | /** |
6624 | * _scsih_hide_unhide_sas_devices - add/remove device to/from OS | ||
6625 | * @ioc: per adapter object | ||
6626 | * | ||
6627 | * Return nothing. | ||
6628 | */ | ||
6629 | static void | ||
6630 | _scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc) | ||
6631 | { | ||
6632 | struct _sas_device *sas_device, *sas_device_next; | ||
6633 | |||
6634 | if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag != | ||
6635 | MFG_PAGE10_HIDE_IF_VOL_PRESENT) | ||
6636 | return; | ||
6637 | |||
6638 | if (ioc->hide_drives) { | ||
6639 | if (_scsih_get_num_volumes(ioc)) | ||
6640 | return; | ||
6641 | ioc->hide_drives = 0; | ||
6642 | list_for_each_entry_safe(sas_device, sas_device_next, | ||
6643 | &ioc->sas_device_list, list) { | ||
6644 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | ||
6645 | sas_device->sas_address_parent)) { | ||
6646 | _scsih_sas_device_remove(ioc, sas_device); | ||
6647 | } else if (!sas_device->starget) { | ||
6648 | mpt2sas_transport_port_remove(ioc, | ||
6649 | sas_device->sas_address, | ||
6650 | sas_device->sas_address_parent); | ||
6651 | _scsih_sas_device_remove(ioc, sas_device); | ||
6652 | } | ||
6653 | } | ||
6654 | } else { | ||
6655 | if (!_scsih_get_num_volumes(ioc)) | ||
6656 | return; | ||
6657 | ioc->hide_drives = 1; | ||
6658 | list_for_each_entry_safe(sas_device, sas_device_next, | ||
6659 | &ioc->sas_device_list, list) { | ||
6660 | mpt2sas_transport_port_remove(ioc, | ||
6661 | sas_device->sas_address, | ||
6662 | sas_device->sas_address_parent); | ||
6663 | } | ||
6664 | } | ||
6665 | } | ||
6666 | |||
6667 | /** | ||
6246 | * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) | 6668 | * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) |
6247 | * @ioc: per adapter object | 6669 | * @ioc: per adapter object |
6248 | * @reset_phase: phase | 6670 | * @reset_phase: phase |
@@ -6326,6 +6748,7 @@ _firmware_event_work(struct work_struct *work) | |||
6326 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, | 6748 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, |
6327 | flags); | 6749 | flags); |
6328 | _scsih_remove_unresponding_sas_devices(ioc); | 6750 | _scsih_remove_unresponding_sas_devices(ioc); |
6751 | _scsih_hide_unhide_sas_devices(ioc); | ||
6329 | return; | 6752 | return; |
6330 | } | 6753 | } |
6331 | 6754 | ||
@@ -6425,6 +6848,53 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
6425 | (Mpi2EventDataIrVolume_t *) | 6848 | (Mpi2EventDataIrVolume_t *) |
6426 | mpi_reply->EventData); | 6849 | mpi_reply->EventData); |
6427 | break; | 6850 | break; |
6851 | case MPI2_EVENT_LOG_ENTRY_ADDED: | ||
6852 | { | ||
6853 | Mpi2EventDataLogEntryAdded_t *log_entry; | ||
6854 | u32 *log_code; | ||
6855 | |||
6856 | if (!ioc->is_warpdrive) | ||
6857 | break; | ||
6858 | |||
6859 | log_entry = (Mpi2EventDataLogEntryAdded_t *) | ||
6860 | mpi_reply->EventData; | ||
6861 | log_code = (u32 *)log_entry->LogData; | ||
6862 | |||
6863 | if (le16_to_cpu(log_entry->LogEntryQualifier) | ||
6864 | != MPT2_WARPDRIVE_LOGENTRY) | ||
6865 | break; | ||
6866 | |||
6867 | switch (le32_to_cpu(*log_code)) { | ||
6868 | case MPT2_WARPDRIVE_LC_SSDT: | ||
6869 | printk(MPT2SAS_WARN_FMT "WarpDrive Warning: " | ||
6870 | "IO Throttling has occurred in the WarpDrive " | ||
6871 | "subsystem. Check WarpDrive documentation for " | ||
6872 | "additional details.\n", ioc->name); | ||
6873 | break; | ||
6874 | case MPT2_WARPDRIVE_LC_SSDLW: | ||
6875 | printk(MPT2SAS_WARN_FMT "WarpDrive Warning: " | ||
6876 | "Program/Erase Cycles for the WarpDrive subsystem " | ||
6877 | "in degraded range. Check WarpDrive documentation " | ||
6878 | "for additional details.\n", ioc->name); | ||
6879 | break; | ||
6880 | case MPT2_WARPDRIVE_LC_SSDLF: | ||
6881 | printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: " | ||
6882 | "There are no Program/Erase Cycles for the " | ||
6883 | "WarpDrive subsystem. The storage device will be " | ||
6884 | "in read-only mode. Check WarpDrive documentation " | ||
6885 | "for additional details.\n", ioc->name); | ||
6886 | break; | ||
6887 | case MPT2_WARPDRIVE_LC_BRMF: | ||
6888 | printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: " | ||
6889 | "The Backup Rail Monitor has failed on the " | ||
6890 | "WarpDrive subsystem. Check WarpDrive " | ||
6891 | "documentation for additional details.\n", | ||
6892 | ioc->name); | ||
6893 | break; | ||
6894 | } | ||
6895 | |||
6896 | break; | ||
6897 | } | ||
6428 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: | 6898 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: |
6429 | case MPI2_EVENT_IR_OPERATION_STATUS: | 6899 | case MPI2_EVENT_IR_OPERATION_STATUS: |
6430 | case MPI2_EVENT_SAS_DISCOVERY: | 6900 | case MPI2_EVENT_SAS_DISCOVERY: |
@@ -6583,7 +7053,8 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc) | |||
6583 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; | 7053 | mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; |
6584 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; | 7054 | mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; |
6585 | 7055 | ||
6586 | printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name); | 7056 | if (!ioc->hide_ir_msg) |
7057 | printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name); | ||
6587 | init_completion(&ioc->scsih_cmds.done); | 7058 | init_completion(&ioc->scsih_cmds.done); |
6588 | mpt2sas_base_put_smid_default(ioc, smid); | 7059 | mpt2sas_base_put_smid_default(ioc, smid); |
6589 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); | 7060 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); |
@@ -6597,10 +7068,11 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc) | |||
6597 | if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) { | 7068 | if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) { |
6598 | mpi_reply = ioc->scsih_cmds.reply; | 7069 | mpi_reply = ioc->scsih_cmds.reply; |
6599 | 7070 | ||
6600 | printk(MPT2SAS_INFO_FMT "IR shutdown (complete): " | 7071 | if (!ioc->hide_ir_msg) |
6601 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | 7072 | printk(MPT2SAS_INFO_FMT "IR shutdown (complete): " |
6602 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), | 7073 | "ioc_status(0x%04x), loginfo(0x%08x)\n", |
6603 | le32_to_cpu(mpi_reply->IOCLogInfo)); | 7074 | ioc->name, le16_to_cpu(mpi_reply->IOCStatus), |
7075 | le32_to_cpu(mpi_reply->IOCLogInfo)); | ||
6604 | } | 7076 | } |
6605 | 7077 | ||
6606 | out: | 7078 | out: |
@@ -6759,6 +7231,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc) | |||
6759 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 7231 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6760 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 7232 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
6761 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7233 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
7234 | |||
7235 | if (ioc->hide_drives) | ||
7236 | return; | ||
6762 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 7237 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
6763 | sas_device->sas_address_parent)) { | 7238 | sas_device->sas_address_parent)) { |
6764 | _scsih_sas_device_remove(ioc, sas_device); | 7239 | _scsih_sas_device_remove(ioc, sas_device); |
@@ -6812,6 +7287,9 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | |||
6812 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 7287 | list_move_tail(&sas_device->list, &ioc->sas_device_list); |
6813 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7288 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
6814 | 7289 | ||
7290 | if (ioc->hide_drives) | ||
7291 | continue; | ||
7292 | |||
6815 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 7293 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
6816 | sas_device->sas_address_parent)) { | 7294 | sas_device->sas_address_parent)) { |
6817 | _scsih_sas_device_remove(ioc, sas_device); | 7295 | _scsih_sas_device_remove(ioc, sas_device); |
@@ -6882,6 +7360,11 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
6882 | ioc->id = mpt_ids++; | 7360 | ioc->id = mpt_ids++; |
6883 | sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id); | 7361 | sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id); |
6884 | ioc->pdev = pdev; | 7362 | ioc->pdev = pdev; |
7363 | if (id->device == MPI2_MFGPAGE_DEVID_SSS6200) { | ||
7364 | ioc->is_warpdrive = 1; | ||
7365 | ioc->hide_ir_msg = 1; | ||
7366 | } else | ||
7367 | ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; | ||
6885 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; | 7368 | ioc->scsi_io_cb_idx = scsi_io_cb_idx; |
6886 | ioc->tm_cb_idx = tm_cb_idx; | 7369 | ioc->tm_cb_idx = tm_cb_idx; |
6887 | ioc->ctl_cb_idx = ctl_cb_idx; | 7370 | ioc->ctl_cb_idx = ctl_cb_idx; |
@@ -6947,6 +7430,20 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
6947 | } | 7430 | } |
6948 | 7431 | ||
6949 | ioc->wait_for_port_enable_to_complete = 0; | 7432 | ioc->wait_for_port_enable_to_complete = 0; |
7433 | if (ioc->is_warpdrive) { | ||
7434 | if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) | ||
7435 | ioc->hide_drives = 0; | ||
7436 | else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS) | ||
7437 | ioc->hide_drives = 1; | ||
7438 | else { | ||
7439 | if (_scsih_get_num_volumes(ioc)) | ||
7440 | ioc->hide_drives = 1; | ||
7441 | else | ||
7442 | ioc->hide_drives = 0; | ||
7443 | } | ||
7444 | } else | ||
7445 | ioc->hide_drives = 0; | ||
7446 | |||
6950 | _scsih_probe_devices(ioc); | 7447 | _scsih_probe_devices(ioc); |
6951 | return 0; | 7448 | return 0; |
6952 | 7449 | ||