diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2008-04-03 16:13:24 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-07 13:19:15 -0400 |
commit | 523ec773b8ffb1c607bc3a54c9526558e3b1eab1 (patch) | |
tree | 9cb3fc8a68af97a6359704e4341652aad9cc65d1 /drivers/scsi/qla2xxx/qla_mbx.c | |
parent | 3fe7cfb910ea138ae623d1320c71e2a7a0bdc527 (diff) |
[SCSI] qla2xxx: Add midlayer target/device reset support.
Now that infrastructure is present within the midlayer and there
is a clear distinction between what is expected from a device and
target reset, convert the current device-reset codes to a
target-reset, and add codes to perform a proper device-reset (LUN
reset).
In the process of adding reset support, collapse and consolidate
large sections of mailbox-command (TMF issuance) codes,
generalize the two 'wait-for-commands-to-complete' functions, and
add a generic-reset routine for use by midlayer reset functions.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 123 |
1 files changed, 82 insertions, 41 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index b25c15a86c7f..c1af56dec4d4 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -784,35 +784,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
784 | return rval; | 784 | return rval; |
785 | } | 785 | } |
786 | 786 | ||
787 | /* | ||
788 | * qla2x00_abort_target | ||
789 | * Issue abort target mailbox command. | ||
790 | * | ||
791 | * Input: | ||
792 | * ha = adapter block pointer. | ||
793 | * | ||
794 | * Returns: | ||
795 | * qla2x00 local function return status code. | ||
796 | * | ||
797 | * Context: | ||
798 | * Kernel context. | ||
799 | */ | ||
800 | int | 787 | int |
801 | qla2x00_abort_target(fc_port_t *fcport) | 788 | qla2x00_abort_target(struct fc_port *fcport, unsigned int l) |
802 | { | 789 | { |
803 | int rval; | 790 | int rval, rval2; |
804 | mbx_cmd_t mc; | 791 | mbx_cmd_t mc; |
805 | mbx_cmd_t *mcp = &mc; | 792 | mbx_cmd_t *mcp = &mc; |
806 | scsi_qla_host_t *ha; | 793 | scsi_qla_host_t *ha; |
807 | 794 | ||
808 | if (fcport == NULL) | ||
809 | return 0; | ||
810 | |||
811 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 795 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
812 | 796 | ||
797 | l = l; | ||
813 | ha = fcport->ha; | 798 | ha = fcport->ha; |
814 | mcp->mb[0] = MBC_ABORT_TARGET; | 799 | mcp->mb[0] = MBC_ABORT_TARGET; |
815 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 800 | mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; |
816 | if (HAS_EXTENDED_IDS(ha)) { | 801 | if (HAS_EXTENDED_IDS(ha)) { |
817 | mcp->mb[1] = fcport->loop_id; | 802 | mcp->mb[1] = fcport->loop_id; |
818 | mcp->mb[10] = 0; | 803 | mcp->mb[10] = 0; |
@@ -821,22 +806,66 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
821 | mcp->mb[1] = fcport->loop_id << 8; | 806 | mcp->mb[1] = fcport->loop_id << 8; |
822 | } | 807 | } |
823 | mcp->mb[2] = ha->loop_reset_delay; | 808 | mcp->mb[2] = ha->loop_reset_delay; |
809 | mcp->mb[9] = ha->vp_idx; | ||
824 | 810 | ||
825 | mcp->in_mb = MBX_0; | 811 | mcp->in_mb = MBX_0; |
826 | mcp->tov = 30; | 812 | mcp->tov = 30; |
827 | mcp->flags = 0; | 813 | mcp->flags = 0; |
828 | rval = qla2x00_mailbox_command(ha, mcp); | 814 | rval = qla2x00_mailbox_command(ha, mcp); |
815 | if (rval != QLA_SUCCESS) { | ||
816 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
817 | ha->host_no, rval)); | ||
818 | } | ||
819 | |||
820 | /* Issue marker IOCB. */ | ||
821 | rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | ||
822 | if (rval2 != QLA_SUCCESS) { | ||
823 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
824 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
825 | } else { | ||
826 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
827 | } | ||
828 | |||
829 | return rval; | ||
830 | } | ||
831 | |||
832 | int | ||
833 | qla2x00_lun_reset(struct fc_port *fcport, unsigned int l) | ||
834 | { | ||
835 | int rval, rval2; | ||
836 | mbx_cmd_t mc; | ||
837 | mbx_cmd_t *mcp = &mc; | ||
838 | scsi_qla_host_t *ha; | ||
839 | |||
840 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | ||
829 | 841 | ||
830 | /* Issue marker command. */ | 842 | ha = fcport->ha; |
831 | ha->marker_needed = 1; | 843 | mcp->mb[0] = MBC_LUN_RESET; |
844 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; | ||
845 | if (HAS_EXTENDED_IDS(ha)) | ||
846 | mcp->mb[1] = fcport->loop_id; | ||
847 | else | ||
848 | mcp->mb[1] = fcport->loop_id << 8; | ||
849 | mcp->mb[2] = l; | ||
850 | mcp->mb[3] = 0; | ||
851 | mcp->mb[9] = ha->vp_idx; | ||
832 | 852 | ||
853 | mcp->in_mb = MBX_0; | ||
854 | mcp->tov = 30; | ||
855 | mcp->flags = 0; | ||
856 | rval = qla2x00_mailbox_command(ha, mcp); | ||
833 | if (rval != QLA_SUCCESS) { | 857 | if (rval != QLA_SUCCESS) { |
834 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", | 858 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
835 | ha->host_no, rval)); | 859 | ha->host_no, rval)); |
860 | } | ||
861 | |||
862 | /* Issue marker IOCB. */ | ||
863 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN); | ||
864 | if (rval2 != QLA_SUCCESS) { | ||
865 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
866 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
836 | } else { | 867 | } else { |
837 | /*EMPTY*/ | 868 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
838 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", | ||
839 | ha->host_no)); | ||
840 | } | 869 | } |
841 | 870 | ||
842 | return rval; | 871 | return rval; |
@@ -2186,17 +2215,15 @@ struct tsk_mgmt_cmd { | |||
2186 | } p; | 2215 | } p; |
2187 | }; | 2216 | }; |
2188 | 2217 | ||
2189 | int | 2218 | static int |
2190 | qla24xx_abort_target(fc_port_t *fcport) | 2219 | __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, |
2220 | unsigned int l) | ||
2191 | { | 2221 | { |
2192 | int rval; | 2222 | int rval, rval2; |
2193 | struct tsk_mgmt_cmd *tsk; | 2223 | struct tsk_mgmt_cmd *tsk; |
2194 | dma_addr_t tsk_dma; | 2224 | dma_addr_t tsk_dma; |
2195 | scsi_qla_host_t *ha, *pha; | 2225 | scsi_qla_host_t *ha, *pha; |
2196 | 2226 | ||
2197 | if (fcport == NULL) | ||
2198 | return 0; | ||
2199 | |||
2200 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 2227 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
2201 | 2228 | ||
2202 | ha = fcport->ha; | 2229 | ha = fcport->ha; |
@@ -2213,47 +2240,61 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2213 | tsk->p.tsk.entry_count = 1; | 2240 | tsk->p.tsk.entry_count = 1; |
2214 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); | 2241 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); |
2215 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 2242 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); |
2216 | tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); | 2243 | tsk->p.tsk.control_flags = cpu_to_le32(type); |
2217 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; | 2244 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; |
2218 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; | 2245 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; |
2219 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; | 2246 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; |
2220 | tsk->p.tsk.vp_index = fcport->vp_idx; | 2247 | tsk->p.tsk.vp_index = fcport->vp_idx; |
2248 | if (type == TCF_LUN_RESET) { | ||
2249 | int_to_scsilun(l, &tsk->p.tsk.lun); | ||
2250 | host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, | ||
2251 | sizeof(tsk->p.tsk.lun)); | ||
2252 | } | ||
2221 | 2253 | ||
2222 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); | 2254 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); |
2223 | if (rval != QLA_SUCCESS) { | 2255 | if (rval != QLA_SUCCESS) { |
2224 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " | 2256 | DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB " |
2225 | "(%x).\n", __func__, ha->host_no, rval)); | 2257 | "(%x).\n", __func__, ha->host_no, name, rval)); |
2226 | goto atarget_done; | ||
2227 | } else if (tsk->p.sts.entry_status != 0) { | 2258 | } else if (tsk->p.sts.entry_status != 0) { |
2228 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2259 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2229 | "-- error status (%x).\n", __func__, ha->host_no, | 2260 | "-- error status (%x).\n", __func__, ha->host_no, |
2230 | tsk->p.sts.entry_status)); | 2261 | tsk->p.sts.entry_status)); |
2231 | rval = QLA_FUNCTION_FAILED; | 2262 | rval = QLA_FUNCTION_FAILED; |
2232 | goto atarget_done; | ||
2233 | } else if (tsk->p.sts.comp_status != | 2263 | } else if (tsk->p.sts.comp_status != |
2234 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2264 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2235 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2265 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2236 | "-- completion status (%x).\n", __func__, | 2266 | "-- completion status (%x).\n", __func__, |
2237 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); | 2267 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); |
2238 | rval = QLA_FUNCTION_FAILED; | 2268 | rval = QLA_FUNCTION_FAILED; |
2239 | goto atarget_done; | ||
2240 | } | 2269 | } |
2241 | 2270 | ||
2242 | /* Issue marker IOCB. */ | 2271 | /* Issue marker IOCB. */ |
2243 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | 2272 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, |
2244 | if (rval != QLA_SUCCESS) { | 2273 | type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID); |
2274 | if (rval2 != QLA_SUCCESS) { | ||
2245 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | 2275 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " |
2246 | "(%x).\n", __func__, ha->host_no, rval)); | 2276 | "(%x).\n", __func__, ha->host_no, rval2)); |
2247 | } else { | 2277 | } else { |
2248 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | 2278 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2249 | } | 2279 | } |
2250 | 2280 | ||
2251 | atarget_done: | ||
2252 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); | 2281 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); |
2253 | 2282 | ||
2254 | return rval; | 2283 | return rval; |
2255 | } | 2284 | } |
2256 | 2285 | ||
2286 | int | ||
2287 | qla24xx_abort_target(struct fc_port *fcport, unsigned int l) | ||
2288 | { | ||
2289 | return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l); | ||
2290 | } | ||
2291 | |||
2292 | int | ||
2293 | qla24xx_lun_reset(struct fc_port *fcport, unsigned int l) | ||
2294 | { | ||
2295 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); | ||
2296 | } | ||
2297 | |||
2257 | #if 0 | 2298 | #if 0 |
2258 | 2299 | ||
2259 | int | 2300 | int |