aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_mbx.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2008-04-03 16:13:24 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-07 13:19:15 -0400
commit523ec773b8ffb1c607bc3a54c9526558e3b1eab1 (patch)
tree9cb3fc8a68af97a6359704e4341652aad9cc65d1 /drivers/scsi/qla2xxx/qla_mbx.c
parent3fe7cfb910ea138ae623d1320c71e2a7a0bdc527 (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.c123
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 */
800int 787int
801qla2x00_abort_target(fc_port_t *fcport) 788qla2x00_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
832int
833qla2x00_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
2189int 2218static int
2190qla24xx_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
2251atarget_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
2286int
2287qla24xx_abort_target(struct fc_port *fcport, unsigned int l)
2288{
2289 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l);
2290}
2291
2292int
2293qla24xx_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
2259int 2300int