1 /* 2 * QLogic iSCSI HBA Driver 3 * Copyright (c) 2011 QLogic Corporation 4 * 5 * See LICENSE.qla4xxx for copyright and licensing details. 6 */ 7 8 #include "ql4_def.h" 9 #include "ql4_glbl.h" 10 #include "ql4_bsg.h" 11 12 static int 13 qla4xxx_read_flash(struct bsg_job *bsg_job) 14 { 15 struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 16 struct scsi_qla_host *ha = to_qla_host(host); 17 struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 18 struct iscsi_bsg_request *bsg_req = bsg_job->request; 19 uint32_t offset = 0; 20 uint32_t length = 0; 21 dma_addr_t flash_dma; 22 uint8_t *flash = NULL; 23 int rval = -EINVAL; 24 25 bsg_reply->reply_payload_rcv_len = 0; 26 27 if (unlikely(pci_channel_offline(ha->pdev))) 28 goto leave; 29 30 if (ql4xxx_reset_active(ha)) { 31 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 32 rval = -EBUSY; 33 goto leave; 34 } 35 36 if (ha->flash_state != QLFLASH_WAITING) { 37 ql4_printk(KERN_ERR, ha, "%s: another flash operation " 38 "active\n", __func__); 39 rval = -EBUSY; 40 goto leave; 41 } 42 43 ha->flash_state = QLFLASH_READING; 44 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 45 length = bsg_job->reply_payload.payload_len; 46 47 flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma, 48 GFP_KERNEL); 49 if (!flash) { 50 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " 51 "data\n", __func__); 52 rval = -ENOMEM; 53 goto leave; 54 } 55 56 rval = qla4xxx_get_flash(ha, flash_dma, offset, length); 57 if (rval) { 58 ql4_printk(KERN_ERR, ha, "%s: get flash failed\n", __func__); 59 bsg_reply->result = DID_ERROR << 16; 60 rval = -EIO; 61 } else { 62 bsg_reply->reply_payload_rcv_len = 63 sg_copy_from_buffer(bsg_job->reply_payload.sg_list, 64 bsg_job->reply_payload.sg_cnt, 65 flash, length); 66 bsg_reply->result = DID_OK << 16; 67 } 68 69 bsg_job_done(bsg_job, bsg_reply->result, 70 bsg_reply->reply_payload_rcv_len); 71 dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); 72 leave: 73 ha->flash_state = QLFLASH_WAITING; 74 return rval; 75 } 76 77 static int 78 qla4xxx_update_flash(struct bsg_job *bsg_job) 79 { 80 struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 81 struct scsi_qla_host *ha = to_qla_host(host); 82 struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 83 struct iscsi_bsg_request *bsg_req = bsg_job->request; 84 uint32_t length = 0; 85 uint32_t offset = 0; 86 uint32_t options = 0; 87 dma_addr_t flash_dma; 88 uint8_t *flash = NULL; 89 int rval = -EINVAL; 90 91 bsg_reply->reply_payload_rcv_len = 0; 92 93 if (unlikely(pci_channel_offline(ha->pdev))) 94 goto leave; 95 96 if (ql4xxx_reset_active(ha)) { 97 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 98 rval = -EBUSY; 99 goto leave; 100 } 101 102 if (ha->flash_state != QLFLASH_WAITING) { 103 ql4_printk(KERN_ERR, ha, "%s: another flash operation " 104 "active\n", __func__); 105 rval = -EBUSY; 106 goto leave; 107 } 108 109 ha->flash_state = QLFLASH_WRITING; 110 length = bsg_job->request_payload.payload_len; 111 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 112 options = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; 113 114 flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma, 115 GFP_KERNEL); 116 if (!flash) { 117 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " 118 "data\n", __func__); 119 rval = -ENOMEM; 120 goto leave; 121 } 122 123 sg_copy_to_buffer(bsg_job->request_payload.sg_list, 124 bsg_job->request_payload.sg_cnt, flash, length); 125 126 rval = qla4xxx_set_flash(ha, flash_dma, offset, length, options); 127 if (rval) { 128 ql4_printk(KERN_ERR, ha, "%s: set flash failed\n", __func__); 129 bsg_reply->result = DID_ERROR << 16; 130 rval = -EIO; 131 } else 132 bsg_reply->result = DID_OK << 16; 133 134 bsg_job_done(bsg_job, bsg_reply->result, 135 bsg_reply->reply_payload_rcv_len); 136 dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); 137 leave: 138 ha->flash_state = QLFLASH_WAITING; 139 return rval; 140 } 141 142 /** 143 * qla4xxx_process_vendor_specific - handle vendor specific bsg request 144 * @job: iscsi_bsg_job to handle 145 **/ 146 int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job) 147 { 148 struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 149 struct iscsi_bsg_request *bsg_req = bsg_job->request; 150 struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 151 struct scsi_qla_host *ha = to_qla_host(host); 152 153 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) { 154 case QLISCSI_VND_READ_FLASH: 155 return qla4xxx_read_flash(bsg_job); 156 157 case QLISCSI_VND_UPDATE_FLASH: 158 return qla4xxx_update_flash(bsg_job); 159 160 default: 161 ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: " 162 "0x%x\n", __func__, bsg_req->msgcode); 163 bsg_reply->result = (DID_ERROR << 16); 164 bsg_reply->reply_payload_rcv_len = 0; 165 bsg_job_done(bsg_job, bsg_reply->result, 166 bsg_reply->reply_payload_rcv_len); 167 return -ENOSYS; 168 } 169 } 170 171 /** 172 * qla4xxx_bsg_request - handle bsg request from ISCSI transport 173 * @job: iscsi_bsg_job to handle 174 */ 175 int qla4xxx_bsg_request(struct bsg_job *bsg_job) 176 { 177 struct iscsi_bsg_request *bsg_req = bsg_job->request; 178 struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 179 struct scsi_qla_host *ha = to_qla_host(host); 180 181 switch (bsg_req->msgcode) { 182 case ISCSI_BSG_HST_VENDOR: 183 return qla4xxx_process_vendor_specific(bsg_job); 184 185 default: 186 ql4_printk(KERN_ERR, ha, "%s: invalid BSG command: 0x%x\n", 187 __func__, bsg_req->msgcode); 188 } 189 190 return -ENOSYS; 191 } 192