aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c568
1 files changed, 401 insertions, 167 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 774b34525bba..86ab32d7ab15 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2,7 +2,7 @@
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers 2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
5 * Copyright (C) 2007-2008 LSI Corporation 5 * Copyright (C) 2007-2009 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -79,6 +79,9 @@ static u8 transport_cb_idx = -1;
79static u8 config_cb_idx = -1; 79static u8 config_cb_idx = -1;
80static int mpt_ids; 80static int mpt_ids;
81 81
82static u8 tm_tr_cb_idx = -1 ;
83static u8 tm_sas_control_cb_idx = -1;
84
82/* command line options */ 85/* command line options */
83static u32 logging_level; 86static u32 logging_level;
84MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " 87MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info "
@@ -109,6 +112,7 @@ struct sense_info {
109 * @work: work object (ioc->fault_reset_work_q) 112 * @work: work object (ioc->fault_reset_work_q)
110 * @ioc: per adapter object 113 * @ioc: per adapter object
111 * @VF_ID: virtual function id 114 * @VF_ID: virtual function id
115 * @VP_ID: virtual port id
112 * @host_reset_handling: handling events during host reset 116 * @host_reset_handling: handling events during host reset
113 * @ignore: flag meaning this event has been marked to ignore 117 * @ignore: flag meaning this event has been marked to ignore
114 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h 118 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
@@ -121,6 +125,7 @@ struct fw_event_work {
121 struct work_struct work; 125 struct work_struct work;
122 struct MPT2SAS_ADAPTER *ioc; 126 struct MPT2SAS_ADAPTER *ioc;
123 u8 VF_ID; 127 u8 VF_ID;
128 u8 VP_ID;
124 u8 host_reset_handling; 129 u8 host_reset_handling;
125 u8 ignore; 130 u8 ignore;
126 u16 event; 131 u16 event;
@@ -138,8 +143,10 @@ struct fw_event_work {
138 * @lun: lun number 143 * @lun: lun number
139 * @cdb_length: cdb length 144 * @cdb_length: cdb length
140 * @cdb: cdb contents 145 * @cdb: cdb contents
141 * @valid_reply: flag set for reply message
142 * @timeout: timeout for this command 146 * @timeout: timeout for this command
147 * @VF_ID: virtual function id
148 * @VP_ID: virtual port id
149 * @valid_reply: flag set for reply message
143 * @sense_length: sense length 150 * @sense_length: sense length
144 * @ioc_status: ioc status 151 * @ioc_status: ioc status
145 * @scsi_state: scsi state 152 * @scsi_state: scsi state
@@ -161,6 +168,8 @@ struct _scsi_io_transfer {
161 u8 cdb_length; 168 u8 cdb_length;
162 u8 cdb[32]; 169 u8 cdb[32];
163 u8 timeout; 170 u8 timeout;
171 u8 VF_ID;
172 u8 VP_ID;
164 u8 valid_reply; 173 u8 valid_reply;
165 /* the following bits are only valid when 'valid_reply = 1' */ 174 /* the following bits are only valid when 'valid_reply = 1' */
166 u32 sense_length; 175 u32 sense_length;
@@ -756,66 +765,16 @@ _scsih_is_end_device(u32 device_info)
756} 765}
757 766
758/** 767/**
759 * _scsih_scsi_lookup_get - returns scmd entry 768 * mptscsih_get_scsi_lookup - returns scmd entry
760 * @ioc: per adapter object 769 * @ioc: per adapter object
761 * @smid: system request message index 770 * @smid: system request message index
762 * Context: This function will acquire ioc->scsi_lookup_lock.
763 * 771 *
764 * Returns the smid stored scmd pointer. 772 * Returns the smid stored scmd pointer.
765 */ 773 */
766static struct scsi_cmnd * 774static struct scsi_cmnd *
767_scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) 775_scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
768{ 776{
769 unsigned long flags; 777 return ioc->scsi_lookup[smid - 1].scmd;
770 struct scsi_cmnd *scmd;
771
772 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
773 scmd = ioc->scsi_lookup[smid - 1].scmd;
774 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
775 return scmd;
776}
777
778/**
779 * mptscsih_getclear_scsi_lookup - returns scmd entry
780 * @ioc: per adapter object
781 * @smid: system request message index
782 * Context: This function will acquire ioc->scsi_lookup_lock.
783 *
784 * Returns the smid stored scmd pointer, as well as clearing the scmd pointer.
785 */
786static struct scsi_cmnd *
787_scsih_scsi_lookup_getclear(struct MPT2SAS_ADAPTER *ioc, u16 smid)
788{
789 unsigned long flags;
790 struct scsi_cmnd *scmd;
791
792 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
793 scmd = ioc->scsi_lookup[smid - 1].scmd;
794 ioc->scsi_lookup[smid - 1].scmd = NULL;
795 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
796 return scmd;
797}
798
799/**
800 * _scsih_scsi_lookup_set - updates scmd entry in lookup
801 * @ioc: per adapter object
802 * @smid: system request message index
803 * @scmd: pointer to scsi command object
804 * Context: This function will acquire ioc->scsi_lookup_lock.
805 *
806 * This will save scmd pointer in the scsi_lookup array.
807 *
808 * Return nothing.
809 */
810static void
811_scsih_scsi_lookup_set(struct MPT2SAS_ADAPTER *ioc, u16 smid,
812 struct scsi_cmnd *scmd)
813{
814 unsigned long flags;
815
816 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
817 ioc->scsi_lookup[smid - 1].scmd = scmd;
818 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
819} 778}
820 779
821/** 780/**
@@ -838,9 +797,9 @@ _scsih_scsi_lookup_find_by_scmd(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd
838 797
839 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 798 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
840 smid = 0; 799 smid = 0;
841 for (i = 0; i < ioc->request_depth; i++) { 800 for (i = 0; i < ioc->scsiio_depth; i++) {
842 if (ioc->scsi_lookup[i].scmd == scmd) { 801 if (ioc->scsi_lookup[i].scmd == scmd) {
843 smid = i + 1; 802 smid = ioc->scsi_lookup[i].smid;
844 goto out; 803 goto out;
845 } 804 }
846 } 805 }
@@ -869,7 +828,7 @@ _scsih_scsi_lookup_find_by_target(struct MPT2SAS_ADAPTER *ioc, int id,
869 828
870 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 829 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
871 found = 0; 830 found = 0;
872 for (i = 0 ; i < ioc->request_depth; i++) { 831 for (i = 0 ; i < ioc->scsiio_depth; i++) {
873 if (ioc->scsi_lookup[i].scmd && 832 if (ioc->scsi_lookup[i].scmd &&
874 (ioc->scsi_lookup[i].scmd->device->id == id && 833 (ioc->scsi_lookup[i].scmd->device->id == id &&
875 ioc->scsi_lookup[i].scmd->device->channel == channel)) { 834 ioc->scsi_lookup[i].scmd->device->channel == channel)) {
@@ -903,7 +862,7 @@ _scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
903 862
904 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 863 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
905 found = 0; 864 found = 0;
906 for (i = 0 ; i < ioc->request_depth; i++) { 865 for (i = 0 ; i < ioc->scsiio_depth; i++) {
907 if (ioc->scsi_lookup[i].scmd && 866 if (ioc->scsi_lookup[i].scmd &&
908 (ioc->scsi_lookup[i].scmd->device->id == id && 867 (ioc->scsi_lookup[i].scmd->device->id == id &&
909 ioc->scsi_lookup[i].scmd->device->channel == channel && 868 ioc->scsi_lookup[i].scmd->device->channel == channel &&
@@ -1113,7 +1072,7 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
1113} 1072}
1114 1073
1115/** 1074/**
1116 * _scsih_change_queue_depth - changing device queue tag type 1075 * _scsih_change_queue_type - changing device queue tag type
1117 * @sdev: scsi device struct 1076 * @sdev: scsi device struct
1118 * @tag_type: requested tag type 1077 * @tag_type: requested tag type
1119 * 1078 *
@@ -1679,23 +1638,24 @@ _scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code)
1679 * _scsih_tm_done - tm completion routine 1638 * _scsih_tm_done - tm completion routine
1680 * @ioc: per adapter object 1639 * @ioc: per adapter object
1681 * @smid: system request message index 1640 * @smid: system request message index
1682 * @VF_ID: virtual function id 1641 * @msix_index: MSIX table index supplied by the OS
1683 * @reply: reply message frame(lower 32bit addr) 1642 * @reply: reply message frame(lower 32bit addr)
1684 * Context: none. 1643 * Context: none.
1685 * 1644 *
1686 * The callback handler when using scsih_issue_tm. 1645 * The callback handler when using scsih_issue_tm.
1687 * 1646 *
1688 * Return nothing. 1647 * Return 1 meaning mf should be freed from _base_interrupt
1648 * 0 means the mf is freed from this function.
1689 */ 1649 */
1690static void 1650static u8
1691_scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) 1651_scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
1692{ 1652{
1693 MPI2DefaultReply_t *mpi_reply; 1653 MPI2DefaultReply_t *mpi_reply;
1694 1654
1695 if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED) 1655 if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED)
1696 return; 1656 return 1;
1697 if (ioc->tm_cmds.smid != smid) 1657 if (ioc->tm_cmds.smid != smid)
1698 return; 1658 return 1;
1699 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; 1659 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
1700 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 1660 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
1701 if (mpi_reply) { 1661 if (mpi_reply) {
@@ -1704,6 +1664,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
1704 } 1664 }
1705 ioc->tm_cmds.status &= ~MPT2_CMD_PENDING; 1665 ioc->tm_cmds.status &= ~MPT2_CMD_PENDING;
1706 complete(&ioc->tm_cmds.done); 1666 complete(&ioc->tm_cmds.done);
1667 return 1;
1707} 1668}
1708 1669
1709/** 1670/**
@@ -1790,7 +1751,6 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1790 u16 smid = 0; 1751 u16 smid = 0;
1791 u32 ioc_state; 1752 u32 ioc_state;
1792 unsigned long timeleft; 1753 unsigned long timeleft;
1793 u8 VF_ID = 0;
1794 1754
1795 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) { 1755 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
1796 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n", 1756 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
@@ -1817,7 +1777,7 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1817 goto issue_host_reset; 1777 goto issue_host_reset;
1818 } 1778 }
1819 1779
1820 smid = mpt2sas_base_get_smid(ioc, ioc->tm_cb_idx); 1780 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
1821 if (!smid) { 1781 if (!smid) {
1822 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1782 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1823 ioc->name, __func__); 1783 ioc->name, __func__);
@@ -1825,7 +1785,8 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1825 } 1785 }
1826 1786
1827 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x)," 1787 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x),"
1828 " task_type(0x%02x), smid(%d)\n", ioc->name, handle, type, smid)); 1788 " task_type(0x%02x), smid(%d)\n", ioc->name, handle, type,
1789 smid_task));
1829 ioc->tm_cmds.status = MPT2_CMD_PENDING; 1790 ioc->tm_cmds.status = MPT2_CMD_PENDING;
1830 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1791 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1831 ioc->tm_cmds.smid = smid; 1792 ioc->tm_cmds.smid = smid;
@@ -1834,10 +1795,12 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1834 mpi_request->DevHandle = cpu_to_le16(handle); 1795 mpi_request->DevHandle = cpu_to_le16(handle);
1835 mpi_request->TaskType = type; 1796 mpi_request->TaskType = type;
1836 mpi_request->TaskMID = cpu_to_le16(smid_task); 1797 mpi_request->TaskMID = cpu_to_le16(smid_task);
1798 mpi_request->VP_ID = 0; /* TODO */
1799 mpi_request->VF_ID = 0;
1837 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); 1800 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
1838 mpt2sas_scsih_set_tm_flag(ioc, handle); 1801 mpt2sas_scsih_set_tm_flag(ioc, handle);
1839 init_completion(&ioc->tm_cmds.done); 1802 init_completion(&ioc->tm_cmds.done);
1840 mpt2sas_base_put_smid_hi_priority(ioc, smid, VF_ID); 1803 mpt2sas_base_put_smid_hi_priority(ioc, smid);
1841 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); 1804 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
1842 mpt2sas_scsih_clear_tm_flag(ioc, handle); 1805 mpt2sas_scsih_clear_tm_flag(ioc, handle);
1843 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) { 1806 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) {
@@ -2075,7 +2038,7 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
2075} 2038}
2076 2039
2077/** 2040/**
2078 * _scsih_abort - eh threads main host reset routine 2041 * _scsih_host_reset - eh threads main host reset routine
2079 * @sdev: scsi device struct 2042 * @sdev: scsi device struct
2080 * 2043 *
2081 * Returns SUCCESS if command aborted else FAILED 2044 * Returns SUCCESS if command aborted else FAILED
@@ -2354,6 +2317,231 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2354} 2317}
2355 2318
2356/** 2319/**
2320 * _scsih_tm_tr_send - send task management request
2321 * @ioc: per adapter object
2322 * @handle: device handle
2323 * Context: interrupt time.
2324 *
2325 * This code is to initiate the device removal handshake protocal
2326 * with controller firmware. This function will issue target reset
2327 * using high priority request queue. It will send a sas iounit
2328 * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion.
2329 *
2330 * This is designed to send muliple task management request at the same
2331 * time to the fifo. If the fifo is full, we will append the request,
2332 * and process it in a future completion.
2333 */
2334static void
2335_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2336{
2337 Mpi2SCSITaskManagementRequest_t *mpi_request;
2338 struct MPT2SAS_TARGET *sas_target_priv_data;
2339 u16 smid;
2340 struct _sas_device *sas_device;
2341 unsigned long flags;
2342 struct _tr_list *delayed_tr;
2343
2344 if (ioc->shost_recovery) {
2345 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2346 __func__, ioc->name);
2347 return;
2348 }
2349
2350 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2351 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2352 if (!sas_device) {
2353 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2354 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2355 ioc->name, __func__);
2356 return;
2357 }
2358 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2359
2360 /* skip is hidden raid component */
2361 if (sas_device->hidden_raid_component)
2362 return;
2363
2364 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
2365 if (!smid) {
2366 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
2367 if (!delayed_tr)
2368 return;
2369 INIT_LIST_HEAD(&delayed_tr->list);
2370 delayed_tr->handle = handle;
2371 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
2372 list_add_tail(&delayed_tr->list,
2373 &ioc->delayed_tr_list);
2374 if (sas_device->starget)
2375 dewtprintk(ioc, starget_printk(KERN_INFO,
2376 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2377 "(open)\n", sas_device->handle));
2378 return;
2379 }
2380
2381 if (sas_device->starget && sas_device->starget->hostdata) {
2382 sas_target_priv_data = sas_device->starget->hostdata;
2383 sas_target_priv_data->tm_busy = 1;
2384 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
2385 "tr:handle(0x%04x), (open)\n", sas_device->handle));
2386 }
2387
2388 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2389 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2390 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2391 mpi_request->DevHandle = cpu_to_le16(handle);
2392 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
2393 sas_device->state |= MPTSAS_STATE_TR_SEND;
2394 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2395 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2396}
2397
2398
2399
2400/**
2401 * _scsih_sas_control_complete - completion routine
2402 * @ioc: per adapter object
2403 * @smid: system request message index
2404 * @msix_index: MSIX table index supplied by the OS
2405 * @reply: reply message frame(lower 32bit addr)
2406 * Context: interrupt time.
2407 *
2408 * This is the sas iounit controll completion routine.
2409 * This code is part of the code to initiate the device removal
2410 * handshake protocal with controller firmware.
2411 *
2412 * Return 1 meaning mf should be freed from _base_interrupt
2413 * 0 means the mf is freed from this function.
2414 */
2415static u8
2416_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2417 u8 msix_index, u32 reply)
2418{
2419 unsigned long flags;
2420 u16 handle;
2421 struct _sas_device *sas_device;
2422 Mpi2SasIoUnitControlReply_t *mpi_reply =
2423 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2424
2425 handle = le16_to_cpu(mpi_reply->DevHandle);
2426
2427 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2428 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2429 if (!sas_device) {
2430 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2431 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2432 ioc->name, __func__);
2433 return 1;
2434 }
2435 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2436 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2437
2438 if (sas_device->starget)
2439 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
2440 "sc_complete:handle(0x%04x), "
2441 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2442 handle, le16_to_cpu(mpi_reply->IOCStatus),
2443 le32_to_cpu(mpi_reply->IOCLogInfo)));
2444 return 1;
2445}
2446
2447/**
2448 * _scsih_tm_tr_complete -
2449 * @ioc: per adapter object
2450 * @smid: system request message index
2451 * @msix_index: MSIX table index supplied by the OS
2452 * @reply: reply message frame(lower 32bit addr)
2453 * Context: interrupt time.
2454 *
2455 * This is the target reset completion routine.
2456 * This code is part of the code to initiate the device removal
2457 * handshake protocal with controller firmware.
2458 * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE)
2459 *
2460 * Return 1 meaning mf should be freed from _base_interrupt
2461 * 0 means the mf is freed from this function.
2462 */
2463static u8
2464_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2465 u32 reply)
2466{
2467 unsigned long flags;
2468 u16 handle;
2469 struct _sas_device *sas_device;
2470 Mpi2SCSITaskManagementReply_t *mpi_reply =
2471 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2472 Mpi2SasIoUnitControlRequest_t *mpi_request;
2473 u16 smid_sas_ctrl;
2474 struct MPT2SAS_TARGET *sas_target_priv_data;
2475 struct _tr_list *delayed_tr;
2476 u8 rc;
2477
2478 handle = le16_to_cpu(mpi_reply->DevHandle);
2479 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2480 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2481 if (!sas_device) {
2482 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2483 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2484 ioc->name, __func__);
2485 return 1;
2486 }
2487 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2488 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2489
2490 if (sas_device->starget)
2491 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
2492 "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), "
2493 "loginfo(0x%08x), completed(%d)\n",
2494 sas_device->handle, (sas_device->state &
2495 MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active",
2496 le16_to_cpu(mpi_reply->IOCStatus),
2497 le32_to_cpu(mpi_reply->IOCLogInfo),
2498 le32_to_cpu(mpi_reply->TerminationCount)));
2499
2500 if (sas_device->starget && sas_device->starget->hostdata) {
2501 sas_target_priv_data = sas_device->starget->hostdata;
2502 sas_target_priv_data->tm_busy = 0;
2503 }
2504
2505 if (!list_empty(&ioc->delayed_tr_list)) {
2506 delayed_tr = list_entry(ioc->delayed_tr_list.next,
2507 struct _tr_list, list);
2508 mpt2sas_base_free_smid(ioc, smid);
2509 if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL)
2510 _scsih_tm_tr_send(ioc, delayed_tr->handle);
2511 list_del(&delayed_tr->list);
2512 kfree(delayed_tr);
2513 rc = 0; /* tells base_interrupt not to free mf */
2514 } else
2515 rc = 1;
2516
2517
2518 if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2519 return rc;
2520
2521 if (ioc->shost_recovery) {
2522 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2523 __func__, ioc->name);
2524 return rc;
2525 }
2526
2527 smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
2528 if (!smid_sas_ctrl) {
2529 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2530 ioc->name, __func__);
2531 return rc;
2532 }
2533
2534 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2535 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2536 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2537 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2538 mpi_request->DevHandle = mpi_reply->DevHandle;
2539 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2540 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2541 return rc;
2542}
2543
2544/**
2357 * _scsih_check_topo_delete_events - sanity check on topo events 2545 * _scsih_check_topo_delete_events - sanity check on topo events
2358 * @ioc: per adapter object 2546 * @ioc: per adapter object
2359 * @event_data: the event data payload 2547 * @event_data: the event data payload
@@ -2375,6 +2563,21 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2375 u16 expander_handle; 2563 u16 expander_handle;
2376 struct _sas_node *sas_expander; 2564 struct _sas_node *sas_expander;
2377 unsigned long flags; 2565 unsigned long flags;
2566 int i, reason_code;
2567 u16 handle;
2568
2569 for (i = 0 ; i < event_data->NumEntries; i++) {
2570 if (event_data->PHY[i].PhyStatus &
2571 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
2572 continue;
2573 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
2574 if (!handle)
2575 continue;
2576 reason_code = event_data->PHY[i].PhyStatus &
2577 MPI2_EVENT_SAS_TOPO_RC_MASK;
2578 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
2579 _scsih_tm_tr_send(ioc, handle);
2580 }
2378 2581
2379 expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); 2582 expander_handle = le16_to_cpu(event_data->ExpanderDevHandle);
2380 if (expander_handle < ioc->sas_hba.num_phys) { 2583 if (expander_handle < ioc->sas_hba.num_phys) {
@@ -2433,8 +2636,8 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
2433 u16 smid; 2636 u16 smid;
2434 u16 count = 0; 2637 u16 count = 0;
2435 2638
2436 for (smid = 1; smid <= ioc->request_depth; smid++) { 2639 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
2437 scmd = _scsih_scsi_lookup_getclear(ioc, smid); 2640 scmd = _scsih_scsi_lookup_get(ioc, smid);
2438 if (!scmd) 2641 if (!scmd)
2439 continue; 2642 continue;
2440 count++; 2643 count++;
@@ -2616,7 +2819,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2616 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) 2819 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON))
2617 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; 2820 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
2618 2821
2619 smid = mpt2sas_base_get_smid(ioc, ioc->scsi_io_cb_idx); 2822 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
2620 if (!smid) { 2823 if (!smid) {
2621 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 2824 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2622 ioc->name, __func__); 2825 ioc->name, __func__);
@@ -2643,7 +2846,8 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2643 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; 2846 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
2644 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI + 2847 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
2645 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR); 2848 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
2646 2849 mpi_request->VF_ID = 0; /* TODO */
2850 mpi_request->VP_ID = 0;
2647 int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *) 2851 int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
2648 mpi_request->LUN); 2852 mpi_request->LUN);
2649 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); 2853 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
@@ -2657,8 +2861,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2657 } 2861 }
2658 } 2862 }
2659 2863
2660 _scsih_scsi_lookup_set(ioc, smid, scmd); 2864 mpt2sas_base_put_smid_scsi_io(ioc, smid,
2661 mpt2sas_base_put_smid_scsi_io(ioc, smid, 0,
2662 sas_device_priv_data->sas_target->handle); 2865 sas_device_priv_data->sas_target->handle);
2663 return 0; 2866 return 0;
2664 2867
@@ -2954,15 +3157,16 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2954 * _scsih_io_done - scsi request callback 3157 * _scsih_io_done - scsi request callback
2955 * @ioc: per adapter object 3158 * @ioc: per adapter object
2956 * @smid: system request message index 3159 * @smid: system request message index
2957 * @VF_ID: virtual function id 3160 * @msix_index: MSIX table index supplied by the OS
2958 * @reply: reply message frame(lower 32bit addr) 3161 * @reply: reply message frame(lower 32bit addr)
2959 * 3162 *
2960 * Callback handler when using scsih_qcmd. 3163 * Callback handler when using _scsih_qcmd.
2961 * 3164 *
2962 * Return nothing. 3165 * Return 1 meaning mf should be freed from _base_interrupt
3166 * 0 means the mf is freed from this function.
2963 */ 3167 */
2964static void 3168static u8
2965_scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) 3169_scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
2966{ 3170{
2967 Mpi2SCSIIORequest_t *mpi_request; 3171 Mpi2SCSIIORequest_t *mpi_request;
2968 Mpi2SCSIIOReply_t *mpi_reply; 3172 Mpi2SCSIIOReply_t *mpi_reply;
@@ -2976,9 +3180,9 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
2976 u32 response_code; 3180 u32 response_code;
2977 3181
2978 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 3182 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
2979 scmd = _scsih_scsi_lookup_getclear(ioc, smid); 3183 scmd = _scsih_scsi_lookup_get(ioc, smid);
2980 if (scmd == NULL) 3184 if (scmd == NULL)
2981 return; 3185 return 1;
2982 3186
2983 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 3187 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2984 3188
@@ -3134,6 +3338,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
3134 out: 3338 out:
3135 scsi_dma_unmap(scmd); 3339 scsi_dma_unmap(scmd);
3136 scmd->scsi_done(scmd); 3340 scmd->scsi_done(scmd);
3341 return 1;
3137} 3342}
3138 3343
3139/** 3344/**
@@ -3398,9 +3603,8 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3398 } 3603 }
3399 } 3604 }
3400 3605
3401 sas_address = le64_to_cpu(expander_pg0.SASAddress);
3402
3403 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3606 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3607 sas_address = le64_to_cpu(expander_pg0.SASAddress);
3404 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, 3608 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3405 sas_address); 3609 sas_address);
3406 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3610 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -3666,6 +3870,12 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3666 if (ioc->remove_host) 3870 if (ioc->remove_host)
3667 goto out; 3871 goto out;
3668 3872
3873 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
3874 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
3875 "target_reset handle(0x%04x)\n", ioc->name, handle));
3876 goto skip_tr;
3877 }
3878
3669 /* Target Reset to flush out all the outstanding IO */ 3879 /* Target Reset to flush out all the outstanding IO */
3670 device_handle = (sas_device->hidden_raid_component) ? 3880 device_handle = (sas_device->hidden_raid_component) ?
3671 sas_device->volume_handle : handle; 3881 sas_device->volume_handle : handle;
@@ -3682,6 +3892,13 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3682 if (ioc->shost_recovery) 3892 if (ioc->shost_recovery)
3683 goto out; 3893 goto out;
3684 } 3894 }
3895 skip_tr:
3896
3897 if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) {
3898 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
3899 "sas_cntrl handle(0x%04x)\n", ioc->name, handle));
3900 goto out;
3901 }
3685 3902
3686 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ 3903 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
3687 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" 3904 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
@@ -3690,7 +3907,8 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3690 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 3907 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
3691 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 3908 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
3692 mpi_request.DevHandle = handle; 3909 mpi_request.DevHandle = handle;
3693 mpi_request.VF_ID = 0; 3910 mpi_request.VF_ID = 0; /* TODO */
3911 mpi_request.VP_ID = 0;
3694 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, 3912 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply,
3695 &mpi_request)) != 0) { 3913 &mpi_request)) != 0) {
3696 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3914 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -3800,15 +4018,12 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3800/** 4018/**
3801 * _scsih_sas_topology_change_event - handle topology changes 4019 * _scsih_sas_topology_change_event - handle topology changes
3802 * @ioc: per adapter object 4020 * @ioc: per adapter object
3803 * @VF_ID: 4021 * @fw_event: The fw_event_work object
3804 * @event_data: event data payload
3805 * fw_event:
3806 * Context: user. 4022 * Context: user.
3807 * 4023 *
3808 */ 4024 */
3809static void 4025static void
3810_scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4026_scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
3811 Mpi2EventDataSasTopologyChangeList_t *event_data,
3812 struct fw_event_work *fw_event) 4027 struct fw_event_work *fw_event)
3813{ 4028{
3814 int i; 4029 int i;
@@ -3818,6 +4033,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3818 struct _sas_node *sas_expander; 4033 struct _sas_node *sas_expander;
3819 unsigned long flags; 4034 unsigned long flags;
3820 u8 link_rate_; 4035 u8 link_rate_;
4036 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
3821 4037
3822#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4038#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3823 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4039 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -3851,15 +4067,16 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3851 } 4067 }
3852 if (ioc->shost_recovery) 4068 if (ioc->shost_recovery)
3853 return; 4069 return;
3854 if (event_data->PHY[i].PhyStatus & 4070 phy_number = event_data->StartPhyNum + i;
3855 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) 4071 reason_code = event_data->PHY[i].PhyStatus &
4072 MPI2_EVENT_SAS_TOPO_RC_MASK;
4073 if ((event_data->PHY[i].PhyStatus &
4074 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && (reason_code !=
4075 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING))
3856 continue; 4076 continue;
3857 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 4077 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
3858 if (!handle) 4078 if (!handle)
3859 continue; 4079 continue;
3860 phy_number = event_data->StartPhyNum + i;
3861 reason_code = event_data->PHY[i].PhyStatus &
3862 MPI2_EVENT_SAS_TOPO_RC_MASK;
3863 link_rate_ = event_data->PHY[i].LinkRate >> 4; 4080 link_rate_ = event_data->PHY[i].LinkRate >> 4;
3864 switch (reason_code) { 4081 switch (reason_code) {
3865 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4082 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
@@ -3971,19 +4188,19 @@ _scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3971/** 4188/**
3972 * _scsih_sas_device_status_change_event - handle device status change 4189 * _scsih_sas_device_status_change_event - handle device status change
3973 * @ioc: per adapter object 4190 * @ioc: per adapter object
3974 * @VF_ID: 4191 * @fw_event: The fw_event_work object
3975 * @event_data: event data payload
3976 * Context: user. 4192 * Context: user.
3977 * 4193 *
3978 * Return nothing. 4194 * Return nothing.
3979 */ 4195 */
3980static void 4196static void
3981_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4197_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
3982 Mpi2EventDataSasDeviceStatusChange_t *event_data) 4198 struct fw_event_work *fw_event)
3983{ 4199{
3984#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4200#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3985 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4201 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
3986 _scsih_sas_device_status_change_event_debug(ioc, event_data); 4202 _scsih_sas_device_status_change_event_debug(ioc,
4203 fw_event->event_data);
3987#endif 4204#endif
3988} 4205}
3989 4206
@@ -4026,34 +4243,33 @@ _scsih_sas_enclosure_dev_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4026/** 4243/**
4027 * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events 4244 * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events
4028 * @ioc: per adapter object 4245 * @ioc: per adapter object
4029 * @VF_ID: 4246 * @fw_event: The fw_event_work object
4030 * @event_data: event data payload
4031 * Context: user. 4247 * Context: user.
4032 * 4248 *
4033 * Return nothing. 4249 * Return nothing.
4034 */ 4250 */
4035static void 4251static void
4036_scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc, 4252_scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4037 u8 VF_ID, Mpi2EventDataSasEnclDevStatusChange_t *event_data) 4253 struct fw_event_work *fw_event)
4038{ 4254{
4039#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4255#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4040 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4256 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4041 _scsih_sas_enclosure_dev_status_change_event_debug(ioc, 4257 _scsih_sas_enclosure_dev_status_change_event_debug(ioc,
4042 event_data); 4258 fw_event->event_data);
4043#endif 4259#endif
4044} 4260}
4045 4261
4046/** 4262/**
4047 * _scsih_sas_broadcast_primative_event - handle broadcast events 4263 * _scsih_sas_broadcast_primative_event - handle broadcast events
4048 * @ioc: per adapter object 4264 * @ioc: per adapter object
4049 * @event_data: event data payload 4265 * @fw_event: The fw_event_work object
4050 * Context: user. 4266 * Context: user.
4051 * 4267 *
4052 * Return nothing. 4268 * Return nothing.
4053 */ 4269 */
4054static void 4270static void
4055_scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4271_scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4056 Mpi2EventDataSasBroadcastPrimitive_t *event_data) 4272 struct fw_event_work *fw_event)
4057{ 4273{
4058 struct scsi_cmnd *scmd; 4274 struct scsi_cmnd *scmd;
4059 u16 smid, handle; 4275 u16 smid, handle;
@@ -4062,11 +4278,12 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4062 u32 termination_count; 4278 u32 termination_count;
4063 u32 query_count; 4279 u32 query_count;
4064 Mpi2SCSITaskManagementReply_t *mpi_reply; 4280 Mpi2SCSITaskManagementReply_t *mpi_reply;
4065 4281#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4282 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
4283#endif
4066 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " 4284 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
4067 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, 4285 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
4068 event_data->PortWidth)); 4286 event_data->PortWidth));
4069
4070 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 4287 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
4071 __func__)); 4288 __func__));
4072 4289
@@ -4074,7 +4291,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4074 termination_count = 0; 4291 termination_count = 0;
4075 query_count = 0; 4292 query_count = 0;
4076 mpi_reply = ioc->tm_cmds.reply; 4293 mpi_reply = ioc->tm_cmds.reply;
4077 for (smid = 1; smid <= ioc->request_depth; smid++) { 4294 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
4078 scmd = _scsih_scsi_lookup_get(ioc, smid); 4295 scmd = _scsih_scsi_lookup_get(ioc, smid);
4079 if (!scmd) 4296 if (!scmd)
4080 continue; 4297 continue;
@@ -4121,23 +4338,25 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4121/** 4338/**
4122 * _scsih_sas_discovery_event - handle discovery events 4339 * _scsih_sas_discovery_event - handle discovery events
4123 * @ioc: per adapter object 4340 * @ioc: per adapter object
4124 * @event_data: event data payload 4341 * @fw_event: The fw_event_work object
4125 * Context: user. 4342 * Context: user.
4126 * 4343 *
4127 * Return nothing. 4344 * Return nothing.
4128 */ 4345 */
4129static void 4346static void
4130_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4347_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,
4131 Mpi2EventDataSasDiscovery_t *event_data) 4348 struct fw_event_work *fw_event)
4132{ 4349{
4350 Mpi2EventDataSasDiscovery_t *event_data = fw_event->event_data;
4351
4133#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4352#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4134 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { 4353 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
4135 printk(MPT2SAS_DEBUG_FMT "discovery event: (%s)", ioc->name, 4354 printk(MPT2SAS_DEBUG_FMT "discovery event: (%s)", ioc->name,
4136 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? 4355 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
4137 "start" : "stop"); 4356 "start" : "stop");
4138 if (event_data->DiscoveryStatus) 4357 if (event_data->DiscoveryStatus)
4139 printk(MPT2SAS_DEBUG_FMT ", discovery_status(0x%08x)", 4358 printk("discovery_status(0x%08x)",
4140 ioc->name, le32_to_cpu(event_data->DiscoveryStatus)); 4359 le32_to_cpu(event_data->DiscoveryStatus));
4141 printk("\n"); 4360 printk("\n");
4142 } 4361 }
4143#endif 4362#endif
@@ -4488,19 +4707,19 @@ _scsih_sas_ir_config_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4488/** 4707/**
4489 * _scsih_sas_ir_config_change_event - handle ir configuration change events 4708 * _scsih_sas_ir_config_change_event - handle ir configuration change events
4490 * @ioc: per adapter object 4709 * @ioc: per adapter object
4491 * @VF_ID: 4710 * @fw_event: The fw_event_work object
4492 * @event_data: event data payload
4493 * Context: user. 4711 * Context: user.
4494 * 4712 *
4495 * Return nothing. 4713 * Return nothing.
4496 */ 4714 */
4497static void 4715static void
4498_scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4716_scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
4499 Mpi2EventDataIrConfigChangeList_t *event_data) 4717 struct fw_event_work *fw_event)
4500{ 4718{
4501 Mpi2EventIrConfigElement_t *element; 4719 Mpi2EventIrConfigElement_t *element;
4502 int i; 4720 int i;
4503 u8 foreign_config; 4721 u8 foreign_config;
4722 Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
4504 4723
4505#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4724#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4506 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4725 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -4543,14 +4762,14 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4543/** 4762/**
4544 * _scsih_sas_ir_volume_event - IR volume event 4763 * _scsih_sas_ir_volume_event - IR volume event
4545 * @ioc: per adapter object 4764 * @ioc: per adapter object
4546 * @event_data: event data payload 4765 * @fw_event: The fw_event_work object
4547 * Context: user. 4766 * Context: user.
4548 * 4767 *
4549 * Return nothing. 4768 * Return nothing.
4550 */ 4769 */
4551static void 4770static void
4552_scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4771_scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
4553 Mpi2EventDataIrVolume_t *event_data) 4772 struct fw_event_work *fw_event)
4554{ 4773{
4555 u64 wwid; 4774 u64 wwid;
4556 unsigned long flags; 4775 unsigned long flags;
@@ -4559,6 +4778,7 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4559 u32 state; 4778 u32 state;
4560 int rc; 4779 int rc;
4561 struct MPT2SAS_TARGET *sas_target_priv_data; 4780 struct MPT2SAS_TARGET *sas_target_priv_data;
4781 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
4562 4782
4563 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) 4783 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
4564 return; 4784 return;
@@ -4628,14 +4848,14 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4628/** 4848/**
4629 * _scsih_sas_ir_physical_disk_event - PD event 4849 * _scsih_sas_ir_physical_disk_event - PD event
4630 * @ioc: per adapter object 4850 * @ioc: per adapter object
4631 * @event_data: event data payload 4851 * @fw_event: The fw_event_work object
4632 * Context: user. 4852 * Context: user.
4633 * 4853 *
4634 * Return nothing. 4854 * Return nothing.
4635 */ 4855 */
4636static void 4856static void
4637_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4857_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4638 Mpi2EventDataIrPhysicalDisk_t *event_data) 4858 struct fw_event_work *fw_event)
4639{ 4859{
4640 u16 handle; 4860 u16 handle;
4641 u32 state; 4861 u32 state;
@@ -4644,6 +4864,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4644 Mpi2ConfigReply_t mpi_reply; 4864 Mpi2ConfigReply_t mpi_reply;
4645 Mpi2SasDevicePage0_t sas_device_pg0; 4865 Mpi2SasDevicePage0_t sas_device_pg0;
4646 u32 ioc_status; 4866 u32 ioc_status;
4867 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
4647 4868
4648 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 4869 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
4649 return; 4870 return;
@@ -4743,33 +4964,33 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
4743/** 4964/**
4744 * _scsih_sas_ir_operation_status_event - handle RAID operation events 4965 * _scsih_sas_ir_operation_status_event - handle RAID operation events
4745 * @ioc: per adapter object 4966 * @ioc: per adapter object
4746 * @VF_ID: 4967 * @fw_event: The fw_event_work object
4747 * @event_data: event data payload
4748 * Context: user. 4968 * Context: user.
4749 * 4969 *
4750 * Return nothing. 4970 * Return nothing.
4751 */ 4971 */
4752static void 4972static void
4753_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4973_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
4754 Mpi2EventDataIrOperationStatus_t *event_data) 4974 struct fw_event_work *fw_event)
4755{ 4975{
4756#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4976#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4757 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4977 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4758 _scsih_sas_ir_operation_status_event_debug(ioc, event_data); 4978 _scsih_sas_ir_operation_status_event_debug(ioc,
4979 fw_event->event_data);
4759#endif 4980#endif
4760} 4981}
4761 4982
4762/** 4983/**
4763 * _scsih_task_set_full - handle task set full 4984 * _scsih_task_set_full - handle task set full
4764 * @ioc: per adapter object 4985 * @ioc: per adapter object
4765 * @event_data: event data payload 4986 * @fw_event: The fw_event_work object
4766 * Context: user. 4987 * Context: user.
4767 * 4988 *
4768 * Throttle back qdepth. 4989 * Throttle back qdepth.
4769 */ 4990 */
4770static void 4991static void
4771_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4992_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
4772 Mpi2EventDataTaskSetFull_t *event_data) 4993 *fw_event)
4773{ 4994{
4774 unsigned long flags; 4995 unsigned long flags;
4775 struct _sas_device *sas_device; 4996 struct _sas_device *sas_device;
@@ -4780,6 +5001,7 @@ _scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4780 u16 handle; 5001 u16 handle;
4781 int id, channel; 5002 int id, channel;
4782 u64 sas_address; 5003 u64 sas_address;
5004 Mpi2EventDataTaskSetFull_t *event_data = fw_event->event_data;
4783 5005
4784 current_depth = le16_to_cpu(event_data->CurrentDepth); 5006 current_depth = le16_to_cpu(event_data->CurrentDepth);
4785 handle = le16_to_cpu(event_data->DevHandle); 5007 handle = le16_to_cpu(event_data->DevHandle);
@@ -4868,6 +5090,10 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
4868 if (sas_device->sas_address == sas_address && 5090 if (sas_device->sas_address == sas_address &&
4869 sas_device->slot == slot && sas_device->starget) { 5091 sas_device->slot == slot && sas_device->starget) {
4870 sas_device->responding = 1; 5092 sas_device->responding = 1;
5093 sas_device->state = 0;
5094 starget = sas_device->starget;
5095 sas_target_priv_data = starget->hostdata;
5096 sas_target_priv_data->tm_busy = 0;
4871 starget_printk(KERN_INFO, sas_device->starget, 5097 starget_printk(KERN_INFO, sas_device->starget,
4872 "handle(0x%04x), sas_addr(0x%016llx), enclosure " 5098 "handle(0x%04x), sas_addr(0x%016llx), enclosure "
4873 "logical id(0x%016llx), slot(%d)\n", handle, 5099 "logical id(0x%016llx), slot(%d)\n", handle,
@@ -4880,8 +5106,6 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
4880 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 5106 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
4881 sas_device->handle); 5107 sas_device->handle);
4882 sas_device->handle = handle; 5108 sas_device->handle = handle;
4883 starget = sas_device->starget;
4884 sas_target_priv_data = starget->hostdata;
4885 sas_target_priv_data->handle = handle; 5109 sas_target_priv_data->handle = handle;
4886 goto out; 5110 goto out;
4887 } 5111 }
@@ -5227,44 +5451,38 @@ _firmware_event_work(struct work_struct *work)
5227 5451
5228 switch (fw_event->event) { 5452 switch (fw_event->event) {
5229 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 5453 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
5230 _scsih_sas_topology_change_event(ioc, fw_event->VF_ID, 5454 _scsih_sas_topology_change_event(ioc, fw_event);
5231 fw_event->event_data, fw_event);
5232 break; 5455 break;
5233 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 5456 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
5234 _scsih_sas_device_status_change_event(ioc, fw_event->VF_ID, 5457 _scsih_sas_device_status_change_event(ioc,
5235 fw_event->event_data); 5458 fw_event);
5236 break; 5459 break;
5237 case MPI2_EVENT_SAS_DISCOVERY: 5460 case MPI2_EVENT_SAS_DISCOVERY:
5238 _scsih_sas_discovery_event(ioc, fw_event->VF_ID, 5461 _scsih_sas_discovery_event(ioc,
5239 fw_event->event_data); 5462 fw_event);
5240 break; 5463 break;
5241 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 5464 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
5242 _scsih_sas_broadcast_primative_event(ioc, fw_event->VF_ID, 5465 _scsih_sas_broadcast_primative_event(ioc,
5243 fw_event->event_data); 5466 fw_event);
5244 break; 5467 break;
5245 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 5468 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
5246 _scsih_sas_enclosure_dev_status_change_event(ioc, 5469 _scsih_sas_enclosure_dev_status_change_event(ioc,
5247 fw_event->VF_ID, fw_event->event_data); 5470 fw_event);
5248 break; 5471 break;
5249 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 5472 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
5250 _scsih_sas_ir_config_change_event(ioc, fw_event->VF_ID, 5473 _scsih_sas_ir_config_change_event(ioc, fw_event);
5251 fw_event->event_data);
5252 break; 5474 break;
5253 case MPI2_EVENT_IR_VOLUME: 5475 case MPI2_EVENT_IR_VOLUME:
5254 _scsih_sas_ir_volume_event(ioc, fw_event->VF_ID, 5476 _scsih_sas_ir_volume_event(ioc, fw_event);
5255 fw_event->event_data);
5256 break; 5477 break;
5257 case MPI2_EVENT_IR_PHYSICAL_DISK: 5478 case MPI2_EVENT_IR_PHYSICAL_DISK:
5258 _scsih_sas_ir_physical_disk_event(ioc, fw_event->VF_ID, 5479 _scsih_sas_ir_physical_disk_event(ioc, fw_event);
5259 fw_event->event_data);
5260 break; 5480 break;
5261 case MPI2_EVENT_IR_OPERATION_STATUS: 5481 case MPI2_EVENT_IR_OPERATION_STATUS:
5262 _scsih_sas_ir_operation_status_event(ioc, fw_event->VF_ID, 5482 _scsih_sas_ir_operation_status_event(ioc, fw_event);
5263 fw_event->event_data);
5264 break; 5483 break;
5265 case MPI2_EVENT_TASK_SET_FULL: 5484 case MPI2_EVENT_TASK_SET_FULL:
5266 _scsih_task_set_full(ioc, fw_event->VF_ID, 5485 _scsih_task_set_full(ioc, fw_event);
5267 fw_event->event_data);
5268 break; 5486 break;
5269 } 5487 }
5270 _scsih_fw_event_free(ioc, fw_event); 5488 _scsih_fw_event_free(ioc, fw_event);
@@ -5273,17 +5491,19 @@ _firmware_event_work(struct work_struct *work)
5273/** 5491/**
5274 * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time) 5492 * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time)
5275 * @ioc: per adapter object 5493 * @ioc: per adapter object
5276 * @VF_ID: virtual function id 5494 * @msix_index: MSIX table index supplied by the OS
5277 * @reply: reply message frame(lower 32bit addr) 5495 * @reply: reply message frame(lower 32bit addr)
5278 * Context: interrupt. 5496 * Context: interrupt.
5279 * 5497 *
5280 * This function merely adds a new work task into ioc->firmware_event_thread. 5498 * This function merely adds a new work task into ioc->firmware_event_thread.
5281 * The tasks are worked from _firmware_event_work in user context. 5499 * The tasks are worked from _firmware_event_work in user context.
5282 * 5500 *
5283 * Return nothing. 5501 * Return 1 meaning mf should be freed from _base_interrupt
5502 * 0 means the mf is freed from this function.
5284 */ 5503 */
5285void 5504u8
5286mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply) 5505mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5506 u32 reply)
5287{ 5507{
5288 struct fw_event_work *fw_event; 5508 struct fw_event_work *fw_event;
5289 Mpi2EventNotificationReply_t *mpi_reply; 5509 Mpi2EventNotificationReply_t *mpi_reply;
@@ -5294,11 +5514,11 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5294 spin_lock_irqsave(&ioc->fw_event_lock, flags); 5514 spin_lock_irqsave(&ioc->fw_event_lock, flags);
5295 if (ioc->fw_events_off || ioc->remove_host) { 5515 if (ioc->fw_events_off || ioc->remove_host) {
5296 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 5516 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5297 return; 5517 return 1;
5298 } 5518 }
5299 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 5519 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5300 5520
5301 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 5521 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
5302 event = le16_to_cpu(mpi_reply->Event); 5522 event = le16_to_cpu(mpi_reply->Event);
5303 5523
5304 switch (event) { 5524 switch (event) {
@@ -5312,7 +5532,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5312 if (baen_data->Primitive != 5532 if (baen_data->Primitive !=
5313 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT || 5533 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT ||
5314 ioc->broadcast_aen_busy) 5534 ioc->broadcast_aen_busy)
5315 return; 5535 return 1;
5316 ioc->broadcast_aen_busy = 1; 5536 ioc->broadcast_aen_busy = 1;
5317 break; 5537 break;
5318 } 5538 }
@@ -5334,14 +5554,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5334 break; 5554 break;
5335 5555
5336 default: /* ignore the rest */ 5556 default: /* ignore the rest */
5337 return; 5557 return 1;
5338 } 5558 }
5339 5559
5340 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); 5560 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
5341 if (!fw_event) { 5561 if (!fw_event) {
5342 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 5562 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5343 ioc->name, __FILE__, __LINE__, __func__); 5563 ioc->name, __FILE__, __LINE__, __func__);
5344 return; 5564 return 1;
5345 } 5565 }
5346 fw_event->event_data = 5566 fw_event->event_data =
5347 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); 5567 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC);
@@ -5349,15 +5569,17 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5349 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 5569 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5350 ioc->name, __FILE__, __LINE__, __func__); 5570 ioc->name, __FILE__, __LINE__, __func__);
5351 kfree(fw_event); 5571 kfree(fw_event);
5352 return; 5572 return 1;
5353 } 5573 }
5354 5574
5355 memcpy(fw_event->event_data, mpi_reply->EventData, 5575 memcpy(fw_event->event_data, mpi_reply->EventData,
5356 mpi_reply->EventDataLength*4); 5576 mpi_reply->EventDataLength*4);
5357 fw_event->ioc = ioc; 5577 fw_event->ioc = ioc;
5358 fw_event->VF_ID = VF_ID; 5578 fw_event->VF_ID = mpi_reply->VF_ID;
5579 fw_event->VP_ID = mpi_reply->VP_ID;
5359 fw_event->event = event; 5580 fw_event->event = event;
5360 _scsih_fw_event_add(ioc, fw_event); 5581 _scsih_fw_event_add(ioc, fw_event);
5582 return 1;
5361} 5583}
5362 5584
5363/* shost template */ 5585/* shost template */
@@ -5617,7 +5839,7 @@ _scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc)
5617} 5839}
5618 5840
5619/** 5841/**
5620 * _scsih_probe_sas - reporting raid volumes to sas transport 5842 * _scsih_probe_sas - reporting sas devices to sas transport
5621 * @ioc: per adapter object 5843 * @ioc: per adapter object
5622 * 5844 *
5623 * Called during initial loading of the driver. 5845 * Called during initial loading of the driver.
@@ -5714,6 +5936,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5714 ioc->base_cb_idx = base_cb_idx; 5936 ioc->base_cb_idx = base_cb_idx;
5715 ioc->transport_cb_idx = transport_cb_idx; 5937 ioc->transport_cb_idx = transport_cb_idx;
5716 ioc->config_cb_idx = config_cb_idx; 5938 ioc->config_cb_idx = config_cb_idx;
5939 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
5940 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
5717 ioc->logging_level = logging_level; 5941 ioc->logging_level = logging_level;
5718 /* misc semaphores and spin locks */ 5942 /* misc semaphores and spin locks */
5719 spin_lock_init(&ioc->ioc_reset_in_progress_lock); 5943 spin_lock_init(&ioc->ioc_reset_in_progress_lock);
@@ -5729,6 +5953,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5729 INIT_LIST_HEAD(&ioc->fw_event_list); 5953 INIT_LIST_HEAD(&ioc->fw_event_list);
5730 INIT_LIST_HEAD(&ioc->raid_device_list); 5954 INIT_LIST_HEAD(&ioc->raid_device_list);
5731 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); 5955 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
5956 INIT_LIST_HEAD(&ioc->delayed_tr_list);
5732 5957
5733 /* init shost parameters */ 5958 /* init shost parameters */
5734 shost->max_cmd_len = 16; 5959 shost->max_cmd_len = 16;
@@ -5745,6 +5970,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5745 5970
5746 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION 5971 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
5747 | SHOST_DIF_TYPE3_PROTECTION); 5972 | SHOST_DIF_TYPE3_PROTECTION);
5973 scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
5748 5974
5749 /* event thread */ 5975 /* event thread */
5750 snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), 5976 snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
@@ -5894,6 +6120,11 @@ _scsih_init(void)
5894 /* ctl module callback handler */ 6120 /* ctl module callback handler */
5895 ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); 6121 ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done);
5896 6122
6123 tm_tr_cb_idx = mpt2sas_base_register_callback_handler(
6124 _scsih_tm_tr_complete);
6125 tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler(
6126 _scsih_sas_control_complete);
6127
5897 mpt2sas_ctl_init(); 6128 mpt2sas_ctl_init();
5898 6129
5899 error = pci_register_driver(&scsih_driver); 6130 error = pci_register_driver(&scsih_driver);
@@ -5924,6 +6155,9 @@ _scsih_exit(void)
5924 mpt2sas_base_release_callback_handler(config_cb_idx); 6155 mpt2sas_base_release_callback_handler(config_cb_idx);
5925 mpt2sas_base_release_callback_handler(ctl_cb_idx); 6156 mpt2sas_base_release_callback_handler(ctl_cb_idx);
5926 6157
6158 mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
6159 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
6160
5927 mpt2sas_ctl_exit(); 6161 mpt2sas_ctl_exit();
5928} 6162}
5929 6163