aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarish Zunjarrao <harish.zunjarrao@qlogic.com>2011-08-12 05:51:27 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-08-27 10:36:44 -0400
commit6085491c34b37fa806f70ccd3fb2bf08416e9e98 (patch)
tree50ee5729de3dfce344ea525ee5c64c896cf7ca06
parent5232f801bd0cfb4122e9a28ff942965c3c485fa7 (diff)
[SCSI] qla4xxx: Added Get ACB support using BSG
This command is used to read ACB params from firmware Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/qla4xxx/ql4_bsg.c68
-rw-r--r--drivers/scsi/qla4xxx/ql4_bsg.h1
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c15
4 files changed, 80 insertions, 8 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_bsg.c b/drivers/scsi/qla4xxx/ql4_bsg.c
index 4704a52eaecd..8acdc582ff6d 100644
--- a/drivers/scsi/qla4xxx/ql4_bsg.c
+++ b/drivers/scsi/qla4xxx/ql4_bsg.c
@@ -381,6 +381,71 @@ leave:
381 return rval; 381 return rval;
382} 382}
383 383
384static int
385qla4xxx_bsg_get_acb(struct bsg_job *bsg_job)
386{
387 struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
388 struct scsi_qla_host *ha = to_qla_host(host);
389 struct iscsi_bsg_request *bsg_req = bsg_job->request;
390 struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
391 uint32_t acb_type = 0;
392 uint32_t len = 0;
393 dma_addr_t acb_dma;
394 uint8_t *acb = NULL;
395 int rval = -EINVAL;
396
397 bsg_reply->reply_payload_rcv_len = 0;
398
399 if (unlikely(pci_channel_offline(ha->pdev)))
400 goto leave;
401
402 /* Only 4022 and above adapters are supported */
403 if (is_qla4010(ha))
404 goto leave;
405
406 if (ql4xxx_reset_active(ha)) {
407 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
408 rval = -EBUSY;
409 goto leave;
410 }
411
412 acb_type = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
413 len = bsg_job->reply_payload.payload_len;
414 if (len < sizeof(struct addr_ctrl_blk)) {
415 ql4_printk(KERN_ERR, ha, "%s: invalid acb len %d\n",
416 __func__, len);
417 rval = -EINVAL;
418 goto leave;
419 }
420
421 acb = dma_alloc_coherent(&ha->pdev->dev, len, &acb_dma, GFP_KERNEL);
422 if (!acb) {
423 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for acb "
424 "data\n", __func__);
425 rval = -ENOMEM;
426 goto leave;
427 }
428
429 rval = qla4xxx_get_acb(ha, acb_dma, acb_type, len);
430 if (rval) {
431 ql4_printk(KERN_ERR, ha, "%s: get acb failed\n", __func__);
432 bsg_reply->result = DID_ERROR << 16;
433 rval = -EIO;
434 } else {
435 bsg_reply->reply_payload_rcv_len =
436 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
437 bsg_job->reply_payload.sg_cnt,
438 acb, len);
439 bsg_reply->result = DID_OK << 16;
440 }
441
442 bsg_job_done(bsg_job, bsg_reply->result,
443 bsg_reply->reply_payload_rcv_len);
444 dma_free_coherent(&ha->pdev->dev, len, acb, acb_dma);
445leave:
446 return rval;
447}
448
384/** 449/**
385 * qla4xxx_process_vendor_specific - handle vendor specific bsg request 450 * qla4xxx_process_vendor_specific - handle vendor specific bsg request
386 * @job: iscsi_bsg_job to handle 451 * @job: iscsi_bsg_job to handle
@@ -411,6 +476,9 @@ int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job)
411 case QLISCSI_VND_RESTORE_DEFAULTS: 476 case QLISCSI_VND_RESTORE_DEFAULTS:
412 return qla4xxx_restore_defaults(bsg_job); 477 return qla4xxx_restore_defaults(bsg_job);
413 478
479 case QLISCSI_VND_GET_ACB:
480 return qla4xxx_bsg_get_acb(bsg_job);
481
414 default: 482 default:
415 ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: " 483 ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: "
416 "0x%x\n", __func__, bsg_req->msgcode); 484 "0x%x\n", __func__, bsg_req->msgcode);
diff --git a/drivers/scsi/qla4xxx/ql4_bsg.h b/drivers/scsi/qla4xxx/ql4_bsg.h
index 84a1391f9865..c6a0364509fd 100644
--- a/drivers/scsi/qla4xxx/ql4_bsg.h
+++ b/drivers/scsi/qla4xxx/ql4_bsg.h
@@ -14,5 +14,6 @@
14#define QLISCSI_VND_READ_NVRAM 4 14#define QLISCSI_VND_READ_NVRAM 4
15#define QLISCSI_VND_UPDATE_NVRAM 5 15#define QLISCSI_VND_UPDATE_NVRAM 5
16#define QLISCSI_VND_RESTORE_DEFAULTS 6 16#define QLISCSI_VND_RESTORE_DEFAULTS 6
17#define QLISCSI_VND_GET_ACB 7
17 18
18#endif 19#endif
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 1a0f60187ad6..160db9d5ea21 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -56,8 +56,8 @@ int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
56int qla4xxx_disable_acb(struct scsi_qla_host *ha); 56int qla4xxx_disable_acb(struct scsi_qla_host *ha);
57int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 57int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
58 uint32_t *mbox_sts, dma_addr_t acb_dma); 58 uint32_t *mbox_sts, dma_addr_t acb_dma);
59int qla4xxx_get_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 59int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
60 uint32_t *mbox_sts, dma_addr_t acb_dma); 60 uint32_t acb_type, uint32_t len);
61int qla4xxx_get_ip_state(struct scsi_qla_host *ha, uint32_t acb_idx, 61int qla4xxx_get_ip_state(struct scsi_qla_host *ha, uint32_t acb_idx,
62 uint32_t ip_idx, uint32_t *sts); 62 uint32_t ip_idx, uint32_t *sts);
63void qla4xxx_mark_device_missing(struct iscsi_cls_session *cls_session); 63void qla4xxx_mark_device_missing(struct iscsi_cls_session *cls_session);
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index dfc38aa8740d..de733a777803 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1425,18 +1425,21 @@ int qla4xxx_disable_acb(struct scsi_qla_host *ha)
1425 return status; 1425 return status;
1426} 1426}
1427 1427
1428int qla4xxx_get_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 1428int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
1429 uint32_t *mbox_sts, dma_addr_t acb_dma) 1429 uint32_t acb_type, uint32_t len)
1430{ 1430{
1431 uint32_t mbox_cmd[MBOX_REG_COUNT];
1432 uint32_t mbox_sts[MBOX_REG_COUNT];
1431 int status = QLA_SUCCESS; 1433 int status = QLA_SUCCESS;
1432 1434
1433 memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); 1435 memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1434 memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); 1436 memset(&mbox_sts, 0, sizeof(mbox_sts));
1437
1435 mbox_cmd[0] = MBOX_CMD_GET_ACB; 1438 mbox_cmd[0] = MBOX_CMD_GET_ACB;
1436 mbox_cmd[1] = 0; /* Primary ACB */ 1439 mbox_cmd[1] = acb_type;
1437 mbox_cmd[2] = LSDW(acb_dma); 1440 mbox_cmd[2] = LSDW(acb_dma);
1438 mbox_cmd[3] = MSDW(acb_dma); 1441 mbox_cmd[3] = MSDW(acb_dma);
1439 mbox_cmd[4] = sizeof(struct addr_ctrl_blk); 1442 mbox_cmd[4] = len;
1440 1443
1441 status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]); 1444 status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);
1442 if (status != QLA_SUCCESS) { 1445 if (status != QLA_SUCCESS) {