diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 568 |
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; | |||
79 | static u8 config_cb_idx = -1; | 79 | static u8 config_cb_idx = -1; |
80 | static int mpt_ids; | 80 | static int mpt_ids; |
81 | 81 | ||
82 | static u8 tm_tr_cb_idx = -1 ; | ||
83 | static u8 tm_sas_control_cb_idx = -1; | ||
84 | |||
82 | /* command line options */ | 85 | /* command line options */ |
83 | static u32 logging_level; | 86 | static u32 logging_level; |
84 | MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " | 87 | MODULE_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 | */ |
766 | static struct scsi_cmnd * | 774 | static 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 | */ | ||
786 | static 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 | */ | ||
810 | static 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 | */ |
1690 | static void | 1650 | static 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 | */ | ||
2334 | static 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 | */ | ||
2415 | static 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 | */ | ||
2463 | static 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 | */ |
2964 | static void | 3168 | static 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 | */ |
3809 | static void | 4025 | static 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 | */ |
3980 | static void | 4196 | static 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 | */ |
4035 | static void | 4251 | static 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 | */ |
4054 | static void | 4270 | static 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 | */ |
4129 | static void | 4346 | static 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 | */ |
4497 | static void | 4715 | static 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 | */ |
4551 | static void | 4770 | static 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 | */ |
4636 | static void | 4856 | static 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 | */ |
4752 | static void | 4972 | static 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 | */ |
4770 | static void | 4991 | static 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 | */ |
5285 | void | 5504 | u8 |
5286 | mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply) | 5505 | mpt2sas_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 | ||