diff options
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_bsg.c | 47 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_bsg.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_glbl.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 26 |
4 files changed, 77 insertions, 0 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_bsg.c b/drivers/scsi/qla4xxx/ql4_bsg.c index c47545356f7b..4704a52eaecd 100644 --- a/drivers/scsi/qla4xxx/ql4_bsg.c +++ b/drivers/scsi/qla4xxx/ql4_bsg.c | |||
@@ -337,6 +337,50 @@ leave: | |||
337 | return rval; | 337 | return rval; |
338 | } | 338 | } |
339 | 339 | ||
340 | static int | ||
341 | qla4xxx_restore_defaults(struct bsg_job *bsg_job) | ||
342 | { | ||
343 | struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); | ||
344 | struct scsi_qla_host *ha = to_qla_host(host); | ||
345 | struct iscsi_bsg_request *bsg_req = bsg_job->request; | ||
346 | struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; | ||
347 | uint32_t region = 0; | ||
348 | uint32_t field0 = 0; | ||
349 | uint32_t field1 = 0; | ||
350 | int rval = -EINVAL; | ||
351 | |||
352 | bsg_reply->reply_payload_rcv_len = 0; | ||
353 | |||
354 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
355 | goto leave; | ||
356 | |||
357 | if (is_qla4010(ha)) | ||
358 | goto leave; | ||
359 | |||
360 | if (ql4xxx_reset_active(ha)) { | ||
361 | ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); | ||
362 | rval = -EBUSY; | ||
363 | goto leave; | ||
364 | } | ||
365 | |||
366 | region = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; | ||
367 | field0 = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; | ||
368 | field1 = bsg_req->rqst_data.h_vendor.vendor_cmd[3]; | ||
369 | |||
370 | rval = qla4xxx_restore_factory_defaults(ha, region, field0, field1); | ||
371 | if (rval) { | ||
372 | ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__); | ||
373 | bsg_reply->result = DID_ERROR << 16; | ||
374 | rval = -EIO; | ||
375 | } else | ||
376 | bsg_reply->result = DID_OK << 16; | ||
377 | |||
378 | bsg_job_done(bsg_job, bsg_reply->result, | ||
379 | bsg_reply->reply_payload_rcv_len); | ||
380 | leave: | ||
381 | return rval; | ||
382 | } | ||
383 | |||
340 | /** | 384 | /** |
341 | * qla4xxx_process_vendor_specific - handle vendor specific bsg request | 385 | * qla4xxx_process_vendor_specific - handle vendor specific bsg request |
342 | * @job: iscsi_bsg_job to handle | 386 | * @job: iscsi_bsg_job to handle |
@@ -364,6 +408,9 @@ int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job) | |||
364 | case QLISCSI_VND_UPDATE_NVRAM: | 408 | case QLISCSI_VND_UPDATE_NVRAM: |
365 | return qla4xxx_update_nvram(bsg_job); | 409 | return qla4xxx_update_nvram(bsg_job); |
366 | 410 | ||
411 | case QLISCSI_VND_RESTORE_DEFAULTS: | ||
412 | return qla4xxx_restore_defaults(bsg_job); | ||
413 | |||
367 | default: | 414 | default: |
368 | ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: " | 415 | ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: " |
369 | "0x%x\n", __func__, bsg_req->msgcode); | 416 | "0x%x\n", __func__, bsg_req->msgcode); |
diff --git a/drivers/scsi/qla4xxx/ql4_bsg.h b/drivers/scsi/qla4xxx/ql4_bsg.h index 71df80d612da..84a1391f9865 100644 --- a/drivers/scsi/qla4xxx/ql4_bsg.h +++ b/drivers/scsi/qla4xxx/ql4_bsg.h | |||
@@ -13,5 +13,6 @@ | |||
13 | #define QLISCSI_VND_GET_ACB_STATE 3 | 13 | #define QLISCSI_VND_GET_ACB_STATE 3 |
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 | 17 | ||
17 | #endif | 18 | #endif |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 35bd0c1ede38..1a0f60187ad6 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -166,6 +166,9 @@ int qla4xxx_get_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, | |||
166 | uint32_t offset, uint32_t size); | 166 | uint32_t offset, uint32_t size); |
167 | int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, | 167 | int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, |
168 | uint32_t offset, uint32_t size); | 168 | uint32_t offset, uint32_t size); |
169 | int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha, | ||
170 | uint32_t region, uint32_t field0, | ||
171 | uint32_t field1); | ||
169 | 172 | ||
170 | /* BSG Functions */ | 173 | /* BSG Functions */ |
171 | int qla4xxx_bsg_request(struct bsg_job *bsg_job); | 174 | int qla4xxx_bsg_request(struct bsg_job *bsg_job); |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index e843758da3d4..dfc38aa8740d 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -1744,3 +1744,29 @@ int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, | |||
1744 | } | 1744 | } |
1745 | return status; | 1745 | return status; |
1746 | } | 1746 | } |
1747 | |||
1748 | int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha, | ||
1749 | uint32_t region, uint32_t field0, | ||
1750 | uint32_t field1) | ||
1751 | { | ||
1752 | int status = QLA_SUCCESS; | ||
1753 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | ||
1754 | uint32_t mbox_sts[MBOX_REG_COUNT]; | ||
1755 | |||
1756 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | ||
1757 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | ||
1758 | |||
1759 | mbox_cmd[0] = MBOX_CMD_RESTORE_FACTORY_DEFAULTS; | ||
1760 | mbox_cmd[3] = region; | ||
1761 | mbox_cmd[4] = field0; | ||
1762 | mbox_cmd[5] = field1; | ||
1763 | |||
1764 | status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], | ||
1765 | &mbox_sts[0]); | ||
1766 | if (status != QLA_SUCCESS) { | ||
1767 | DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed " | ||
1768 | "status %04X\n", ha->host_no, __func__, | ||
1769 | mbox_sts[0])); | ||
1770 | } | ||
1771 | return status; | ||
1772 | } | ||