Merge branch 'master' into for-2.6.35
[safe/jmp/linux-2.6] / drivers / scsi / qla2xxx / qla_attr.c
index 5a19aea..1c7ef55 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kthread.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 static int qla24xx_vport_disable(struct fc_vport *, bool);
@@ -1274,7 +1275,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
        int rval = QLA_FUNCTION_FAILED;
        uint16_t state[5];
 
-       if (!vha->hw->flags.eeh_busy)
+       if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+               test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+               DEBUG2_3_11(printk("%s(%ld): isp reset in progress.\n",
+                       __func__, vha->host_no));
+       else if (!vha->hw->flags.eeh_busy)
                rval = qla2x00_get_firmware_state(vha, state);
        if (rval != QLA_SUCCESS)
                memset(state, -1, sizeof(state));
@@ -1531,8 +1536,6 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
                fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
                        fcport->loop_id, fcport->d_id.b.domain,
                        fcport->d_id.b.area, fcport->d_id.b.al_pa);
-
-       qla2x00_abort_fcport_cmds(fcport);
 }
 
 static int
@@ -1882,12 +1885,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
                ha = vha->hw;
                type = "FC_BSG_RPT_ELS";
 
-               DEBUG2(printk(KERN_INFO
-                   "scsi(%ld): loop-id=%x portid=%02x%02x%02x.\n",
-                   fcport->vha->host_no, fcport->loop_id,
-                   fcport->d_id.b.domain, fcport->d_id.b.area,
-                   fcport->d_id.b.al_pa));
-
                /* make sure the rport is logged in,
                 * if not perform fabric login
                 */
@@ -1904,11 +1901,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
                ha = vha->hw;
                type = "FC_BSG_HST_ELS_NOLOGIN";
 
-               DEBUG2(printk(KERN_INFO
-                   "scsi(%ld): loop-id=%x portid=%02x%02x%02x.\n",
-                   vha->host_no, vha->loop_id,
-                   vha->d_id.b.domain, vha->d_id.b.area, vha->d_id.b.al_pa));
-
                /* Allocate a dummy fcport structure, since functions
                 * preparing the IOCB and mailbox command retrieves port
                 * specific information from fcport structure. For Host based
@@ -1934,9 +1926,12 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
                    NPH_FABRIC_CONTROLLER : NPH_F_PORT;
        }
 
-       DEBUG2(printk(KERN_INFO
-           "scsi(%ld): vendor-id = %llu\n",
-           vha->host_no, host->hostt->vendor_id));
+       if (!vha->flags.online) {
+               DEBUG2(qla_printk(KERN_WARNING, ha,
+                   "host not online\n"));
+               rval = -EIO;
+               goto done;
+       }
 
         req_sg_cnt =
            dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
@@ -2059,6 +2054,13 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
                 goto done_unmap_sg;
        }
 
+       if (!vha->flags.online) {
+               DEBUG2(qla_printk(KERN_WARNING, ha,
+                   "host not online\n"));
+               rval = -EIO;
+                goto done_unmap_sg;
+       }
+
        loop_id =
            (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
            >> 24;
@@ -2161,6 +2163,13 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
                goto done;
        }
 
+       if (!vha->flags.online) {
+               DEBUG2(qla_printk(KERN_WARNING, ha,
+                   "host not online\n"));
+               rval = -EIO;
+                goto done;
+       }
+
         elreq.req_sg_cnt =
            dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
            bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -2219,20 +2228,10 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
                if (ha->current_topology != ISP_CFG_F) {
                        type = "FC_BSG_HST_VENDOR_LOOPBACK";
 
-                       if ((IS_QLA81XX(ha)) &&
-                               ((elreq.options == 0) || (elreq.options == 2))) {
-                               DEBUG2(qla_printk(KERN_INFO, ha, "scsi(%ld)"
-                               "loopback option:0x%x not supported\n", vha->host_no, elreq.options));
-                               rval = -EINVAL;
-                               goto done_unmap_sg;
-                       }
-
                        DEBUG2(qla_printk(KERN_INFO, ha,
                                "scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n",
                                vha->host_no, type, vendor_cmd, elreq.options));
-                       DEBUG2(qla_printk(KERN_INFO, ha,
-                               "scsi(%ld) tx_addr: 0x%llx rx_addr: 0x%llx tx_sg_cnt: %x rx_sg_cnt: %x\n",
-                               vha->host_no, (unsigned long long)elreq.send_dma, (unsigned long long)elreq.rcv_dma, elreq.req_sg_cnt, elreq.rsp_sg_cnt));
+
                        command_sent = INT_DEF_LB_LOOPBACK_CMD;
                        rval = qla2x00_loopback_test(vha, &elreq, response);
                        if (IS_QLA81XX(ha)) {
@@ -2248,9 +2247,7 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
                        DEBUG2(qla_printk(KERN_INFO, ha,
                                "scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n",
                                vha->host_no, type, vendor_cmd, elreq.options));
-                       DEBUG2(qla_printk(KERN_INFO, ha,
-                               "scsi(%ld) tx_addr: 0x%llx rx_addr: 0x%llx tx_sg_cnt: %x rx_sg_cnt: %x\n",
-                               vha->host_no, (unsigned long long)elreq.send_dma, (unsigned long long)elreq.rcv_dma, elreq.req_sg_cnt, elreq.rsp_sg_cnt));
+
                        command_sent = INT_DEF_LB_ECHO_CMD;
                        rval = qla2x00_echo_test(vha, &elreq, response);
                }
@@ -2284,6 +2281,7 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
                        "scsi(%ld) Vendor request %s failed\n", vha->host_no, type));
                rval = 0;
                bsg_job->reply->result = (DID_ERROR << 16);
+               bsg_job->reply->reply_payload_rcv_len = 0;
                fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
                memcpy( fw_sts_ptr, response, sizeof(response));
                fw_sts_ptr += sizeof(response);
@@ -2352,60 +2350,50 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
         scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
         struct qla_hw_data *ha = vha->hw;
         srb_t *sp;
-        int i;
+        int cnt, que;
         unsigned long flags;
-        uint16_t que_id;
         struct req_que *req;
-        struct rsp_que *rsp;
-       int found = 0;
        struct srb_bsg *sp_bsg;
 
        /* find the bsg job from the active list of commands */
         spin_lock_irqsave(&ha->hardware_lock, flags);
-       req = ha->req_q_map[0];
-        que_id = req->id;
-        if (req->rsp)
-                rsp = req->rsp;
-        else
-                rsp = ha->rsp_q_map[que_id];
-
-       for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++ ) {
-                sp = req->outstanding_cmds[i];
-
-                if (sp == NULL)
-                        continue;
-
-               sp_bsg = (struct srb_bsg*)sp->ctx;
+       for (que = 0; que < ha->max_req_queues; que++) {
+               req = ha->req_q_map[que];
+               if (!req)
+                       continue;
 
-               if (((sp_bsg->ctx.type == SRB_CT_CMD) ||
-                   (sp_bsg->ctx.type == SRB_ELS_CMD_RPT)
-                   || ( sp_bsg->ctx.type == SRB_ELS_CMD_HST)) &&
-                   (sp_bsg->bsg_job == bsg_job)) {
-                       DEBUG2(qla_printk(KERN_INFO, ha,
-                           "scsi(%ld) req_q: %p rsp_q: %p que_id: %x sp: %p\n",
-                           vha->host_no, req, rsp, que_id, sp));
-                       found = 1;
-                       break;
+               for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++ ) {
+                       sp = req->outstanding_cmds[cnt];
+
+                       if (sp) {
+                               sp_bsg = (struct srb_bsg*)sp->ctx;
+
+                               if (((sp_bsg->ctx.type == SRB_CT_CMD) ||
+                                   (sp_bsg->ctx.type == SRB_ELS_CMD_RPT)
+                                   || ( sp_bsg->ctx.type == SRB_ELS_CMD_HST)) &&
+                                   (sp_bsg->bsg_job == bsg_job)) {
+                                       if (ha->isp_ops->abort_command(sp)) {
+                                               DEBUG2(qla_printk(KERN_INFO, ha,
+                                               "scsi(%ld): mbx abort_command failed\n", vha->host_no));
+                                               bsg_job->req->errors = bsg_job->reply->result = -EIO;
+                                       } else {
+                                               DEBUG2(qla_printk(KERN_INFO, ha,
+                                               "scsi(%ld): mbx abort_command success\n", vha->host_no));
+                                               bsg_job->req->errors = bsg_job->reply->result = 0;
+                                       }
+                                       goto done;
+                               }
+                       }
                }
        }
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
-       if (!found) {
-               DEBUG2(qla_printk(KERN_INFO, ha,
-                       "scsi(%ld) SRB not found to abort\n", vha->host_no));
-               bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
-               return 0;
-       }
-
-       if (ha->isp_ops->abort_command(sp)) {
-               DEBUG2(qla_printk(KERN_INFO, ha,
-               "scsi(%ld): mbx abort_command failed\n", vha->host_no));
-               bsg_job->req->errors = bsg_job->reply->result = -EIO;
-       } else {
-               DEBUG2(qla_printk(KERN_INFO, ha,
-               "scsi(%ld): mbx abort_command success\n", vha->host_no));
-               bsg_job->req->errors = bsg_job->reply->result = 0;
-       }
+       DEBUG2(qla_printk(KERN_INFO, ha,
+               "scsi(%ld) SRB not found to abort\n", vha->host_no));
+       bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
+       return 0;
 
+done:
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
        if (bsg_job->request->msgcode == FC_BSG_HST_CT)
                kfree(sp->fcport);
        kfree(sp->ctx);