1a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary/* 2a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * QLogic iSCSI HBA Driver 3a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * Copyright (c) 2011 QLogic Corporation 4a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * 5a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * See LICENSE.qla4xxx for copyright and licensing details. 6a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary */ 7a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 8a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary#include "ql4_def.h" 9a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary#include "ql4_glbl.h" 10a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary#include "ql4_bsg.h" 11a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 12a355943ca847ca3a264d468e408217562234d019Vikas Chaudharystatic int 13a355943ca847ca3a264d468e408217562234d019Vikas Chaudharyqla4xxx_read_flash(struct bsg_job *bsg_job) 14a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary{ 15a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 16a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct scsi_qla_host *ha = to_qla_host(host); 17a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 18a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct iscsi_bsg_request *bsg_req = bsg_job->request; 19a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary uint32_t offset = 0; 20a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary uint32_t length = 0; 21a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary dma_addr_t flash_dma; 22a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary uint8_t *flash = NULL; 23ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao int rval = -EINVAL; 24a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 25a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary bsg_reply->reply_payload_rcv_len = 0; 26a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 27a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary if (unlikely(pci_channel_offline(ha->pdev))) 28ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 29a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 30ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao if (ql4xxx_reset_active(ha)) { 31ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 32ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = -EBUSY; 33ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 34ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao } 35a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 36ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao if (ha->flash_state != QLFLASH_WAITING) { 37ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: another flash operation " 38ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao "active\n", __func__); 39ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = -EBUSY; 40ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 41a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary } 42a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 43ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ha->flash_state = QLFLASH_READING; 44a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 45a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary length = bsg_job->reply_payload.payload_len; 46a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 47a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma, 48a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary GFP_KERNEL); 49a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary if (!flash) { 50a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " 51a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary "data\n", __func__); 52a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary rval = -ENOMEM; 53ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 54a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary } 55a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 56ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = qla4xxx_get_flash(ha, flash_dma, offset, length); 57ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao if (rval) { 58ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: get flash failed\n", __func__); 59ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_reply->result = DID_ERROR << 16; 60ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = -EIO; 61ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao } else { 62ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_reply->reply_payload_rcv_len = 63ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao sg_copy_from_buffer(bsg_job->reply_payload.sg_list, 64ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_job->reply_payload.sg_cnt, 65ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao flash, length); 66ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_reply->result = DID_OK << 16; 67a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary } 68a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 69ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_job_done(bsg_job, bsg_reply->result, 70ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_reply->reply_payload_rcv_len); 71ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); 72ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarraoleave: 73a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary ha->flash_state = QLFLASH_WAITING; 74a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary return rval; 75a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary} 76a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 77a355943ca847ca3a264d468e408217562234d019Vikas Chaudharystatic int 78a355943ca847ca3a264d468e408217562234d019Vikas Chaudharyqla4xxx_update_flash(struct bsg_job *bsg_job) 79a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary{ 80a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 81a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct scsi_qla_host *ha = to_qla_host(host); 82a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 83a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct iscsi_bsg_request *bsg_req = bsg_job->request; 84a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary uint32_t length = 0; 85a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary uint32_t offset = 0; 86a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary uint32_t options = 0; 87a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary dma_addr_t flash_dma; 88a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary uint8_t *flash = NULL; 89ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao int rval = -EINVAL; 90a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 91a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary bsg_reply->reply_payload_rcv_len = 0; 92a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 93a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary if (unlikely(pci_channel_offline(ha->pdev))) 94ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 95a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 96ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao if (ql4xxx_reset_active(ha)) { 97ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 98ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = -EBUSY; 99ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 100ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao } 101a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 102ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao if (ha->flash_state != QLFLASH_WAITING) { 103ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: another flash operation " 104ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao "active\n", __func__); 105ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = -EBUSY; 106ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 107a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary } 108a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 109ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ha->flash_state = QLFLASH_WRITING; 110a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary length = bsg_job->request_payload.payload_len; 111a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 112a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary options = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; 113a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 114a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma, 115a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary GFP_KERNEL); 116a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary if (!flash) { 117a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " 118a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary "data\n", __func__); 119a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary rval = -ENOMEM; 120ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao goto leave; 121a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary } 122a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 123a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary sg_copy_to_buffer(bsg_job->request_payload.sg_list, 124a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary bsg_job->request_payload.sg_cnt, flash, length); 125a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 126ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = qla4xxx_set_flash(ha, flash_dma, offset, length, options); 127ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao if (rval) { 128ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: set flash failed\n", __func__); 129ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_reply->result = DID_ERROR << 16; 130ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao rval = -EIO; 131ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao } else 132ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_reply->result = DID_OK << 16; 133ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao 134ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_job_done(bsg_job, bsg_reply->result, 135ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao bsg_reply->reply_payload_rcv_len); 136ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarrao dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); 137ef7830bb62c9edf34fc4e849a53d7e87bf51de4aHarish Zunjarraoleave: 138a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary ha->flash_state = QLFLASH_WAITING; 139a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary return rval; 140a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary} 141a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 1428b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarraostatic int 1438b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarraoqla4xxx_get_acb_state(struct bsg_job *bsg_job) 1448b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao{ 1458b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 1468b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao struct scsi_qla_host *ha = to_qla_host(host); 1478b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao struct iscsi_bsg_request *bsg_req = bsg_job->request; 1488b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 1498b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao uint32_t status[MBOX_REG_COUNT]; 1508b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao uint32_t acb_idx; 1518b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao uint32_t ip_idx; 1528b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao int rval = -EINVAL; 1538b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1548b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 0; 1558b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1568b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao if (unlikely(pci_channel_offline(ha->pdev))) 1578b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao goto leave; 1588b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1598b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao /* Only 4022 and above adapters are supported */ 1608b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao if (is_qla4010(ha)) 1618b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao goto leave; 1628b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1638b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao if (ql4xxx_reset_active(ha)) { 1648b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 1658b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao rval = -EBUSY; 1668b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao goto leave; 1678b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao } 1688b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1698b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao if (bsg_job->reply_payload.payload_len < sizeof(status)) { 1708b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: invalid payload len %d\n", 1718b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao __func__, bsg_job->reply_payload.payload_len); 1728b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao rval = -EINVAL; 1738b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao goto leave; 1748b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao } 1758b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1768b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao acb_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 1778b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao ip_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; 1788b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1798b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao rval = qla4xxx_get_ip_state(ha, acb_idx, ip_idx, status); 1808b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao if (rval) { 1818b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: get ip state failed\n", 1828b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao __func__); 1838b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao bsg_reply->result = DID_ERROR << 16; 1848b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao rval = -EIO; 1858b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao } else { 1868b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 1878b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao sg_copy_from_buffer(bsg_job->reply_payload.sg_list, 1888b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao bsg_job->reply_payload.sg_cnt, 1898b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao status, sizeof(status)); 1908b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao bsg_reply->result = DID_OK << 16; 1918b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao } 1928b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1938b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao bsg_job_done(bsg_job, bsg_reply->result, 1948b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao bsg_reply->reply_payload_rcv_len); 1958b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarraoleave: 1968b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao return rval; 1978b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao} 1988b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 1997c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarraostatic int 2007c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarraoqla4xxx_read_nvram(struct bsg_job *bsg_job) 2017c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao{ 2027c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 2037c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct scsi_qla_host *ha = to_qla_host(host); 2047c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct iscsi_bsg_request *bsg_req = bsg_job->request; 2057c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 2067c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint32_t offset = 0; 2077c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint32_t len = 0; 2087c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint32_t total_len = 0; 2097c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao dma_addr_t nvram_dma; 2107c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint8_t *nvram = NULL; 2117c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao int rval = -EINVAL; 2127c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2137c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 0; 2147c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2157c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (unlikely(pci_channel_offline(ha->pdev))) 2167c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2177c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2187c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao /* Only 40xx adapters are supported */ 2197c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha))) 2207c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2217c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2227c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (ql4xxx_reset_active(ha)) { 2237c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 2247c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = -EBUSY; 2257c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2267c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } 2277c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2287c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 2297c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao len = bsg_job->reply_payload.payload_len; 2307c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao total_len = offset + len; 2317c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2327c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao /* total len should not be greater than max NVRAM size */ 2337c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) || 2347c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ((is_qla4022(ha) || is_qla4032(ha)) && 2357c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao total_len > QL40X2_NVRAM_SIZE)) { 2367c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max" 2377c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao " nvram size, offset=%d len=%d\n", 2387c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao __func__, offset, len); 2397c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2407c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } 2417c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2427c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma, 2437c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao GFP_KERNEL); 2447c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (!nvram) { 2457c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for nvram " 2467c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao "data\n", __func__); 2477c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = -ENOMEM; 2487c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2497c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } 2507c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2517c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = qla4xxx_get_nvram(ha, nvram_dma, offset, len); 2527c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (rval) { 2537c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: get nvram failed\n", __func__); 2547c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->result = DID_ERROR << 16; 2557c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = -EIO; 2567c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } else { 2577c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 2587c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao sg_copy_from_buffer(bsg_job->reply_payload.sg_list, 2597c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_job->reply_payload.sg_cnt, 2607c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao nvram, len); 2617c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->result = DID_OK << 16; 2627c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } 2637c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2647c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_job_done(bsg_job, bsg_reply->result, 2657c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->reply_payload_rcv_len); 2667c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma); 2677c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarraoleave: 2687c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao return rval; 2697c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao} 2707c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2717c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarraostatic int 2727c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarraoqla4xxx_update_nvram(struct bsg_job *bsg_job) 2737c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao{ 2747c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 2757c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct scsi_qla_host *ha = to_qla_host(host); 2767c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct iscsi_bsg_request *bsg_req = bsg_job->request; 2777c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 2787c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint32_t offset = 0; 2797c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint32_t len = 0; 2807c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint32_t total_len = 0; 2817c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao dma_addr_t nvram_dma; 2827c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao uint8_t *nvram = NULL; 2837c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao int rval = -EINVAL; 2847c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2857c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 0; 2867c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2877c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (unlikely(pci_channel_offline(ha->pdev))) 2887c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2897c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2907c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha))) 2917c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2927c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2937c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (ql4xxx_reset_active(ha)) { 2947c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 2957c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = -EBUSY; 2967c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 2977c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } 2987c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 2997c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 3007c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao len = bsg_job->request_payload.payload_len; 3017c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao total_len = offset + len; 3027c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 3037c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao /* total len should not be greater than max NVRAM size */ 3047c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) || 3057c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ((is_qla4022(ha) || is_qla4032(ha)) && 3067c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao total_len > QL40X2_NVRAM_SIZE)) { 3077c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max" 3087c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao " nvram size, offset=%d len=%d\n", 3097c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao __func__, offset, len); 3107c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 3117c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } 3127c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 3137c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma, 3147c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao GFP_KERNEL); 3157c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (!nvram) { 3167c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " 3177c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao "data\n", __func__); 3187c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = -ENOMEM; 3197c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao goto leave; 3207c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } 3217c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 3227c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao sg_copy_to_buffer(bsg_job->request_payload.sg_list, 3237c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_job->request_payload.sg_cnt, nvram, len); 3247c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 3257c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = qla4xxx_set_nvram(ha, nvram_dma, offset, len); 3267c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao if (rval) { 3277c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__); 3287c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->result = DID_ERROR << 16; 3297c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao rval = -EIO; 3307c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao } else 3317c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->result = DID_OK << 16; 3327c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 3337c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_job_done(bsg_job, bsg_reply->result, 3347c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao bsg_reply->reply_payload_rcv_len); 3357c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma); 3367c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarraoleave: 3377c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao return rval; 3387c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao} 3397c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 3405232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarraostatic int 3415232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarraoqla4xxx_restore_defaults(struct bsg_job *bsg_job) 3425232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao{ 3435232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 3445232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao struct scsi_qla_host *ha = to_qla_host(host); 3455232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao struct iscsi_bsg_request *bsg_req = bsg_job->request; 3465232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 3475232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao uint32_t region = 0; 3485232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao uint32_t field0 = 0; 3495232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao uint32_t field1 = 0; 3505232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao int rval = -EINVAL; 3515232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3525232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 0; 3535232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3545232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao if (unlikely(pci_channel_offline(ha->pdev))) 3555232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao goto leave; 3565232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3575232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao if (is_qla4010(ha)) 3585232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao goto leave; 3595232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3605232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao if (ql4xxx_reset_active(ha)) { 3615232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 3625232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao rval = -EBUSY; 3635232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao goto leave; 3645232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao } 3655232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3665232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao region = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 3675232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao field0 = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; 3685232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao field1 = bsg_req->rqst_data.h_vendor.vendor_cmd[3]; 3695232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3705232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao rval = qla4xxx_restore_factory_defaults(ha, region, field0, field1); 3715232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao if (rval) { 3725232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__); 3735232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao bsg_reply->result = DID_ERROR << 16; 3745232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao rval = -EIO; 3755232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao } else 3765232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao bsg_reply->result = DID_OK << 16; 3775232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3785232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao bsg_job_done(bsg_job, bsg_reply->result, 3795232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao bsg_reply->reply_payload_rcv_len); 3805232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarraoleave: 3815232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao return rval; 3825232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao} 3835232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 3846085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarraostatic int 3856085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarraoqla4xxx_bsg_get_acb(struct bsg_job *bsg_job) 3866085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao{ 3876085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 3886085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao struct scsi_qla_host *ha = to_qla_host(host); 3896085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao struct iscsi_bsg_request *bsg_req = bsg_job->request; 3906085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 3916085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao uint32_t acb_type = 0; 3926085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao uint32_t len = 0; 3936085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao dma_addr_t acb_dma; 3946085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao uint8_t *acb = NULL; 3956085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao int rval = -EINVAL; 3966085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 3976085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 0; 3986085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 3996085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao if (unlikely(pci_channel_offline(ha->pdev))) 4006085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao goto leave; 4016085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 4026085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao /* Only 4022 and above adapters are supported */ 4036085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao if (is_qla4010(ha)) 4046085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao goto leave; 4056085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 4066085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao if (ql4xxx_reset_active(ha)) { 4076085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); 4086085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao rval = -EBUSY; 4096085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao goto leave; 4106085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao } 4116085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 4126085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao acb_type = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 4136085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao len = bsg_job->reply_payload.payload_len; 4146085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao if (len < sizeof(struct addr_ctrl_blk)) { 4156085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: invalid acb len %d\n", 4166085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao __func__, len); 4176085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao rval = -EINVAL; 4186085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao goto leave; 4196085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao } 4206085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 4216085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao acb = dma_alloc_coherent(&ha->pdev->dev, len, &acb_dma, GFP_KERNEL); 4226085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao if (!acb) { 4236085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for acb " 4246085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao "data\n", __func__); 4256085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao rval = -ENOMEM; 4266085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao goto leave; 4276085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao } 4286085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 4296085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao rval = qla4xxx_get_acb(ha, acb_dma, acb_type, len); 4306085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao if (rval) { 4316085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao ql4_printk(KERN_ERR, ha, "%s: get acb failed\n", __func__); 4326085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao bsg_reply->result = DID_ERROR << 16; 4336085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao rval = -EIO; 4346085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao } else { 4356085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao bsg_reply->reply_payload_rcv_len = 4366085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao sg_copy_from_buffer(bsg_job->reply_payload.sg_list, 4376085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao bsg_job->reply_payload.sg_cnt, 4386085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao acb, len); 4396085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao bsg_reply->result = DID_OK << 16; 4406085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao } 4416085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 4426085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao bsg_job_done(bsg_job, bsg_reply->result, 4436085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao bsg_reply->reply_payload_rcv_len); 4446085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao dma_free_coherent(&ha->pdev->dev, len, acb, acb_dma); 4456085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarraoleave: 4466085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao return rval; 4476085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao} 4486085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 449a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary/** 450a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * qla4xxx_process_vendor_specific - handle vendor specific bsg request 451a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * @job: iscsi_bsg_job to handle 452a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary **/ 453a355943ca847ca3a264d468e408217562234d019Vikas Chaudharyint qla4xxx_process_vendor_specific(struct bsg_job *bsg_job) 454a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary{ 455a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; 456a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct iscsi_bsg_request *bsg_req = bsg_job->request; 457a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 458a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct scsi_qla_host *ha = to_qla_host(host); 459a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 460a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) { 461a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary case QLISCSI_VND_READ_FLASH: 462a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary return qla4xxx_read_flash(bsg_job); 463a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 464a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary case QLISCSI_VND_UPDATE_FLASH: 465a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary return qla4xxx_update_flash(bsg_job); 466a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 4678b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao case QLISCSI_VND_GET_ACB_STATE: 4688b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao return qla4xxx_get_acb_state(bsg_job); 4698b0402e1383cd51121f05a1d249cde0212c28c99Harish Zunjarrao 4707c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao case QLISCSI_VND_READ_NVRAM: 4717c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao return qla4xxx_read_nvram(bsg_job); 4727c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 4737c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao case QLISCSI_VND_UPDATE_NVRAM: 4747c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao return qla4xxx_update_nvram(bsg_job); 4757c07d139cfec3172e813b468a8a173ad73bb5da9Harish Zunjarrao 4765232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao case QLISCSI_VND_RESTORE_DEFAULTS: 4775232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao return qla4xxx_restore_defaults(bsg_job); 4785232f801bd0cfb4122e9a28ff942965c3c485fa7Harish Zunjarrao 4796085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao case QLISCSI_VND_GET_ACB: 4806085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao return qla4xxx_bsg_get_acb(bsg_job); 4816085491c34b37fa806f70ccd3fb2bf08416e9e98Harish Zunjarrao 482a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary default: 483a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: " 484a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary "0x%x\n", __func__, bsg_req->msgcode); 485a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary bsg_reply->result = (DID_ERROR << 16); 486a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary bsg_reply->reply_payload_rcv_len = 0; 487a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary bsg_job_done(bsg_job, bsg_reply->result, 488a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary bsg_reply->reply_payload_rcv_len); 489a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary return -ENOSYS; 490a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary } 491a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary} 492a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 493a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary/** 494a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * qla4xxx_bsg_request - handle bsg request from ISCSI transport 495a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary * @job: iscsi_bsg_job to handle 496a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary */ 497a355943ca847ca3a264d468e408217562234d019Vikas Chaudharyint qla4xxx_bsg_request(struct bsg_job *bsg_job) 498a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary{ 499a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct iscsi_bsg_request *bsg_req = bsg_job->request; 500a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct Scsi_Host *host = iscsi_job_to_shost(bsg_job); 501a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary struct scsi_qla_host *ha = to_qla_host(host); 502a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 503a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary switch (bsg_req->msgcode) { 504a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary case ISCSI_BSG_HST_VENDOR: 505a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary return qla4xxx_process_vendor_specific(bsg_job); 506a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 507a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary default: 508a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary ql4_printk(KERN_ERR, ha, "%s: invalid BSG command: 0x%x\n", 509a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary __func__, bsg_req->msgcode); 510a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary } 511a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary 512a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary return -ENOSYS; 513a355943ca847ca3a264d468e408217562234d019Vikas Chaudhary} 514