root/drivers/scsi/qla4xxx/ql4_bsg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qla4xxx_read_flash
  2. qla4xxx_update_flash
  3. qla4xxx_get_acb_state
  4. qla4xxx_read_nvram
  5. qla4xxx_update_nvram
  6. qla4xxx_restore_defaults
  7. qla4xxx_bsg_get_acb
  8. ql4xxx_execute_diag_cmd
  9. qla4_83xx_wait_for_loopback_config_comp
  10. qla4_83xx_pre_loopback_config
  11. qla4_83xx_post_loopback_config
  12. qla4xxx_execute_diag_loopback_cmd
  13. qla4xxx_execute_diag_test
  14. qla4xxx_process_vendor_specific
  15. qla4xxx_bsg_request

   1 /*
   2  * QLogic iSCSI HBA Driver
   3  * Copyright (c) 2011-2013 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 static int
 143 qla4xxx_get_acb_state(struct bsg_job *bsg_job)
 144 {
 145         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 146         struct scsi_qla_host *ha = to_qla_host(host);
 147         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 148         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
 149         uint32_t status[MBOX_REG_COUNT];
 150         uint32_t acb_idx;
 151         uint32_t ip_idx;
 152         int rval = -EINVAL;
 153 
 154         bsg_reply->reply_payload_rcv_len = 0;
 155 
 156         if (unlikely(pci_channel_offline(ha->pdev)))
 157                 goto leave;
 158 
 159         /* Only 4022 and above adapters are supported */
 160         if (is_qla4010(ha))
 161                 goto leave;
 162 
 163         if (ql4xxx_reset_active(ha)) {
 164                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
 165                 rval = -EBUSY;
 166                 goto leave;
 167         }
 168 
 169         if (bsg_job->reply_payload.payload_len < sizeof(status)) {
 170                 ql4_printk(KERN_ERR, ha, "%s: invalid payload len %d\n",
 171                            __func__, bsg_job->reply_payload.payload_len);
 172                 rval = -EINVAL;
 173                 goto leave;
 174         }
 175 
 176         acb_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
 177         ip_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
 178 
 179         rval = qla4xxx_get_ip_state(ha, acb_idx, ip_idx, status);
 180         if (rval) {
 181                 ql4_printk(KERN_ERR, ha, "%s: get ip state failed\n",
 182                            __func__);
 183                 bsg_reply->result = DID_ERROR << 16;
 184                 rval = -EIO;
 185         } else {
 186                 bsg_reply->reply_payload_rcv_len =
 187                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 188                                             bsg_job->reply_payload.sg_cnt,
 189                                             status, sizeof(status));
 190                 bsg_reply->result = DID_OK << 16;
 191         }
 192 
 193         bsg_job_done(bsg_job, bsg_reply->result,
 194                      bsg_reply->reply_payload_rcv_len);
 195 leave:
 196         return rval;
 197 }
 198 
 199 static int
 200 qla4xxx_read_nvram(struct bsg_job *bsg_job)
 201 {
 202         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 203         struct scsi_qla_host *ha = to_qla_host(host);
 204         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 205         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
 206         uint32_t offset = 0;
 207         uint32_t len = 0;
 208         uint32_t total_len = 0;
 209         dma_addr_t nvram_dma;
 210         uint8_t *nvram = NULL;
 211         int rval = -EINVAL;
 212 
 213         bsg_reply->reply_payload_rcv_len = 0;
 214 
 215         if (unlikely(pci_channel_offline(ha->pdev)))
 216                 goto leave;
 217 
 218         /* Only 40xx adapters are supported */
 219         if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha)))
 220                 goto leave;
 221 
 222         if (ql4xxx_reset_active(ha)) {
 223                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
 224                 rval = -EBUSY;
 225                 goto leave;
 226         }
 227 
 228         offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
 229         len = bsg_job->reply_payload.payload_len;
 230         total_len = offset + len;
 231 
 232         /* total len should not be greater than max NVRAM size */
 233         if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) ||
 234             ((is_qla4022(ha) || is_qla4032(ha)) &&
 235              total_len > QL40X2_NVRAM_SIZE)) {
 236                 ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max"
 237                            " nvram size, offset=%d len=%d\n",
 238                            __func__, offset, len);
 239                 goto leave;
 240         }
 241 
 242         nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma,
 243                                    GFP_KERNEL);
 244         if (!nvram) {
 245                 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for nvram "
 246                            "data\n", __func__);
 247                 rval = -ENOMEM;
 248                 goto leave;
 249         }
 250 
 251         rval = qla4xxx_get_nvram(ha, nvram_dma, offset, len);
 252         if (rval) {
 253                 ql4_printk(KERN_ERR, ha, "%s: get nvram failed\n", __func__);
 254                 bsg_reply->result = DID_ERROR << 16;
 255                 rval = -EIO;
 256         } else {
 257                 bsg_reply->reply_payload_rcv_len =
 258                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 259                                             bsg_job->reply_payload.sg_cnt,
 260                                             nvram, len);
 261                 bsg_reply->result = DID_OK << 16;
 262         }
 263 
 264         bsg_job_done(bsg_job, bsg_reply->result,
 265                      bsg_reply->reply_payload_rcv_len);
 266         dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma);
 267 leave:
 268         return rval;
 269 }
 270 
 271 static int
 272 qla4xxx_update_nvram(struct bsg_job *bsg_job)
 273 {
 274         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 275         struct scsi_qla_host *ha = to_qla_host(host);
 276         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 277         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
 278         uint32_t offset = 0;
 279         uint32_t len = 0;
 280         uint32_t total_len = 0;
 281         dma_addr_t nvram_dma;
 282         uint8_t *nvram = NULL;
 283         int rval = -EINVAL;
 284 
 285         bsg_reply->reply_payload_rcv_len = 0;
 286 
 287         if (unlikely(pci_channel_offline(ha->pdev)))
 288                 goto leave;
 289 
 290         if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha)))
 291                 goto leave;
 292 
 293         if (ql4xxx_reset_active(ha)) {
 294                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
 295                 rval = -EBUSY;
 296                 goto leave;
 297         }
 298 
 299         offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
 300         len = bsg_job->request_payload.payload_len;
 301         total_len = offset + len;
 302 
 303         /* total len should not be greater than max NVRAM size */
 304         if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) ||
 305             ((is_qla4022(ha) || is_qla4032(ha)) &&
 306              total_len > QL40X2_NVRAM_SIZE)) {
 307                 ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max"
 308                            " nvram size, offset=%d len=%d\n",
 309                            __func__, offset, len);
 310                 goto leave;
 311         }
 312 
 313         nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma,
 314                                    GFP_KERNEL);
 315         if (!nvram) {
 316                 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash "
 317                            "data\n", __func__);
 318                 rval = -ENOMEM;
 319                 goto leave;
 320         }
 321 
 322         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
 323                           bsg_job->request_payload.sg_cnt, nvram, len);
 324 
 325         rval = qla4xxx_set_nvram(ha, nvram_dma, offset, len);
 326         if (rval) {
 327                 ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__);
 328                 bsg_reply->result = DID_ERROR << 16;
 329                 rval = -EIO;
 330         } else
 331                 bsg_reply->result = DID_OK << 16;
 332 
 333         bsg_job_done(bsg_job, bsg_reply->result,
 334                      bsg_reply->reply_payload_rcv_len);
 335         dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma);
 336 leave:
 337         return rval;
 338 }
 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 
 384 static int
 385 qla4xxx_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);
 445 leave:
 446         return rval;
 447 }
 448 
 449 static void ql4xxx_execute_diag_cmd(struct bsg_job *bsg_job)
 450 {
 451         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 452         struct scsi_qla_host *ha = to_qla_host(host);
 453         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 454         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
 455         uint8_t *rsp_ptr = NULL;
 456         uint32_t mbox_cmd[MBOX_REG_COUNT];
 457         uint32_t mbox_sts[MBOX_REG_COUNT];
 458         int status = QLA_ERROR;
 459 
 460         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
 461 
 462         if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
 463                 ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
 464                            __func__);
 465                 bsg_reply->result = DID_ERROR << 16;
 466                 goto exit_diag_mem_test;
 467         }
 468 
 469         bsg_reply->reply_payload_rcv_len = 0;
 470         memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
 471                sizeof(uint32_t) * MBOX_REG_COUNT);
 472 
 473         DEBUG2(ql4_printk(KERN_INFO, ha,
 474                           "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
 475                           __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
 476                           mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
 477                           mbox_cmd[7]));
 478 
 479         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
 480                                          &mbox_sts[0]);
 481 
 482         DEBUG2(ql4_printk(KERN_INFO, ha,
 483                           "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
 484                           __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
 485                           mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
 486                           mbox_sts[7]));
 487 
 488         if (status == QLA_SUCCESS)
 489                 bsg_reply->result = DID_OK << 16;
 490         else
 491                 bsg_reply->result = DID_ERROR << 16;
 492 
 493         /* Send mbox_sts to application */
 494         bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
 495         rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
 496         memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
 497 
 498 exit_diag_mem_test:
 499         DEBUG2(ql4_printk(KERN_INFO, ha,
 500                           "%s: bsg_reply->result = x%x, status = %s\n",
 501                           __func__, bsg_reply->result, STATUS(status)));
 502 
 503         bsg_job_done(bsg_job, bsg_reply->result,
 504                      bsg_reply->reply_payload_rcv_len);
 505 }
 506 
 507 static int qla4_83xx_wait_for_loopback_config_comp(struct scsi_qla_host *ha,
 508                                                    int wait_for_link)
 509 {
 510         int status = QLA_SUCCESS;
 511 
 512         if (!wait_for_completion_timeout(&ha->idc_comp, (IDC_COMP_TOV * HZ))) {
 513                 ql4_printk(KERN_INFO, ha, "%s: IDC Complete notification not received, Waiting for another %d timeout",
 514                            __func__, ha->idc_extend_tmo);
 515                 if (ha->idc_extend_tmo) {
 516                         if (!wait_for_completion_timeout(&ha->idc_comp,
 517                                                 (ha->idc_extend_tmo * HZ))) {
 518                                 ha->notify_idc_comp = 0;
 519                                 ha->notify_link_up_comp = 0;
 520                                 ql4_printk(KERN_WARNING, ha, "%s: Aborting: IDC Complete notification not received",
 521                                            __func__);
 522                                 status = QLA_ERROR;
 523                                 goto exit_wait;
 524                         } else {
 525                                 DEBUG2(ql4_printk(KERN_INFO, ha,
 526                                                   "%s: IDC Complete notification received\n",
 527                                                   __func__));
 528                         }
 529                 }
 530         } else {
 531                 DEBUG2(ql4_printk(KERN_INFO, ha,
 532                                   "%s: IDC Complete notification received\n",
 533                                   __func__));
 534         }
 535         ha->notify_idc_comp = 0;
 536 
 537         if (wait_for_link) {
 538                 if (!wait_for_completion_timeout(&ha->link_up_comp,
 539                                                  (IDC_COMP_TOV * HZ))) {
 540                         ha->notify_link_up_comp = 0;
 541                         ql4_printk(KERN_WARNING, ha, "%s: Aborting: LINK UP notification not received",
 542                                    __func__);
 543                         status = QLA_ERROR;
 544                         goto exit_wait;
 545                 } else {
 546                         DEBUG2(ql4_printk(KERN_INFO, ha,
 547                                           "%s: LINK UP notification received\n",
 548                                           __func__));
 549                 }
 550                 ha->notify_link_up_comp = 0;
 551         }
 552 
 553 exit_wait:
 554         return status;
 555 }
 556 
 557 static int qla4_83xx_pre_loopback_config(struct scsi_qla_host *ha,
 558                                          uint32_t *mbox_cmd)
 559 {
 560         uint32_t config = 0;
 561         int status = QLA_SUCCESS;
 562 
 563         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
 564 
 565         status = qla4_83xx_get_port_config(ha, &config);
 566         if (status != QLA_SUCCESS)
 567                 goto exit_pre_loopback_config;
 568 
 569         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Default port config=%08X\n",
 570                           __func__, config));
 571 
 572         if ((config & ENABLE_INTERNAL_LOOPBACK) ||
 573             (config & ENABLE_EXTERNAL_LOOPBACK)) {
 574                 ql4_printk(KERN_INFO, ha, "%s: Loopback diagnostics already in progress. Invalid request\n",
 575                            __func__);
 576                 goto exit_pre_loopback_config;
 577         }
 578 
 579         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
 580                 config |= ENABLE_INTERNAL_LOOPBACK;
 581 
 582         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
 583                 config |= ENABLE_EXTERNAL_LOOPBACK;
 584 
 585         config &= ~ENABLE_DCBX;
 586 
 587         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: New port config=%08X\n",
 588                           __func__, config));
 589 
 590         ha->notify_idc_comp = 1;
 591         ha->notify_link_up_comp = 1;
 592 
 593         /* get the link state */
 594         qla4xxx_get_firmware_state(ha);
 595 
 596         status = qla4_83xx_set_port_config(ha, &config);
 597         if (status != QLA_SUCCESS) {
 598                 ha->notify_idc_comp = 0;
 599                 ha->notify_link_up_comp = 0;
 600                 goto exit_pre_loopback_config;
 601         }
 602 exit_pre_loopback_config:
 603         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
 604                           STATUS(status)));
 605         return status;
 606 }
 607 
 608 static int qla4_83xx_post_loopback_config(struct scsi_qla_host *ha,
 609                                           uint32_t *mbox_cmd)
 610 {
 611         int status = QLA_SUCCESS;
 612         uint32_t config = 0;
 613 
 614         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
 615 
 616         status = qla4_83xx_get_port_config(ha, &config);
 617         if (status != QLA_SUCCESS)
 618                 goto exit_post_loopback_config;
 619 
 620         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: port config=%08X\n", __func__,
 621                           config));
 622 
 623         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
 624                 config &= ~ENABLE_INTERNAL_LOOPBACK;
 625         else if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
 626                 config &= ~ENABLE_EXTERNAL_LOOPBACK;
 627 
 628         config |= ENABLE_DCBX;
 629 
 630         DEBUG2(ql4_printk(KERN_INFO, ha,
 631                           "%s: Restore default port config=%08X\n", __func__,
 632                           config));
 633 
 634         ha->notify_idc_comp = 1;
 635         if (ha->addl_fw_state & FW_ADDSTATE_LINK_UP)
 636                 ha->notify_link_up_comp = 1;
 637 
 638         status = qla4_83xx_set_port_config(ha, &config);
 639         if (status != QLA_SUCCESS) {
 640                 ql4_printk(KERN_INFO, ha, "%s: Scheduling adapter reset\n",
 641                            __func__);
 642                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
 643                 clear_bit(AF_LOOPBACK, &ha->flags);
 644                 goto exit_post_loopback_config;
 645         }
 646 
 647 exit_post_loopback_config:
 648         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
 649                           STATUS(status)));
 650         return status;
 651 }
 652 
 653 static void qla4xxx_execute_diag_loopback_cmd(struct bsg_job *bsg_job)
 654 {
 655         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 656         struct scsi_qla_host *ha = to_qla_host(host);
 657         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 658         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
 659         uint8_t *rsp_ptr = NULL;
 660         uint32_t mbox_cmd[MBOX_REG_COUNT];
 661         uint32_t mbox_sts[MBOX_REG_COUNT];
 662         int wait_for_link = 1;
 663         int status = QLA_ERROR;
 664 
 665         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
 666 
 667         bsg_reply->reply_payload_rcv_len = 0;
 668 
 669         if (test_bit(AF_LOOPBACK, &ha->flags)) {
 670                 ql4_printk(KERN_INFO, ha, "%s: Loopback Diagnostics already in progress. Invalid Request\n",
 671                            __func__);
 672                 bsg_reply->result = DID_ERROR << 16;
 673                 goto exit_loopback_cmd;
 674         }
 675 
 676         if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
 677                 ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
 678                            __func__);
 679                 bsg_reply->result = DID_ERROR << 16;
 680                 goto exit_loopback_cmd;
 681         }
 682 
 683         memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
 684                sizeof(uint32_t) * MBOX_REG_COUNT);
 685 
 686         if (is_qla8032(ha) || is_qla8042(ha)) {
 687                 status = qla4_83xx_pre_loopback_config(ha, mbox_cmd);
 688                 if (status != QLA_SUCCESS) {
 689                         bsg_reply->result = DID_ERROR << 16;
 690                         goto exit_loopback_cmd;
 691                 }
 692 
 693                 status = qla4_83xx_wait_for_loopback_config_comp(ha,
 694                                                                  wait_for_link);
 695                 if (status != QLA_SUCCESS) {
 696                         bsg_reply->result = DID_TIME_OUT << 16;
 697                         goto restore;
 698                 }
 699         }
 700 
 701         DEBUG2(ql4_printk(KERN_INFO, ha,
 702                           "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
 703                           __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
 704                           mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
 705                           mbox_cmd[7]));
 706 
 707         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
 708                                 &mbox_sts[0]);
 709 
 710         if (status == QLA_SUCCESS)
 711                 bsg_reply->result = DID_OK << 16;
 712         else
 713                 bsg_reply->result = DID_ERROR << 16;
 714 
 715         DEBUG2(ql4_printk(KERN_INFO, ha,
 716                           "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
 717                           __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
 718                           mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
 719                           mbox_sts[7]));
 720 
 721         /* Send mbox_sts to application */
 722         bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
 723         rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
 724         memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
 725 restore:
 726         if (is_qla8032(ha) || is_qla8042(ha)) {
 727                 status = qla4_83xx_post_loopback_config(ha, mbox_cmd);
 728                 if (status != QLA_SUCCESS) {
 729                         bsg_reply->result = DID_ERROR << 16;
 730                         goto exit_loopback_cmd;
 731                 }
 732 
 733                 /* for pre_loopback_config() wait for LINK UP only
 734                  * if PHY LINK is UP */
 735                 if (!(ha->addl_fw_state & FW_ADDSTATE_LINK_UP))
 736                         wait_for_link = 0;
 737 
 738                 status = qla4_83xx_wait_for_loopback_config_comp(ha,
 739                                                                  wait_for_link);
 740                 if (status != QLA_SUCCESS) {
 741                         bsg_reply->result = DID_TIME_OUT << 16;
 742                         goto exit_loopback_cmd;
 743                 }
 744         }
 745 exit_loopback_cmd:
 746         DEBUG2(ql4_printk(KERN_INFO, ha,
 747                           "%s: bsg_reply->result = x%x, status = %s\n",
 748                           __func__, bsg_reply->result, STATUS(status)));
 749         bsg_job_done(bsg_job, bsg_reply->result,
 750                      bsg_reply->reply_payload_rcv_len);
 751 }
 752 
 753 static int qla4xxx_execute_diag_test(struct bsg_job *bsg_job)
 754 {
 755         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 756         struct scsi_qla_host *ha = to_qla_host(host);
 757         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 758         uint32_t diag_cmd;
 759         int rval = -EINVAL;
 760 
 761         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
 762 
 763         diag_cmd = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
 764         if (diag_cmd == MBOX_CMD_DIAG_TEST) {
 765                 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[2]) {
 766                 case QL_DIAG_CMD_TEST_DDR_SIZE:
 767                 case QL_DIAG_CMD_TEST_DDR_RW:
 768                 case QL_DIAG_CMD_TEST_ONCHIP_MEM_RW:
 769                 case QL_DIAG_CMD_TEST_NVRAM:
 770                 case QL_DIAG_CMD_TEST_FLASH_ROM:
 771                 case QL_DIAG_CMD_TEST_DMA_XFER:
 772                 case QL_DIAG_CMD_SELF_DDR_RW:
 773                 case QL_DIAG_CMD_SELF_ONCHIP_MEM_RW:
 774                         /* Execute diag test for adapter RAM/FLASH */
 775                         ql4xxx_execute_diag_cmd(bsg_job);
 776                         /* Always return success as we want to sent bsg_reply
 777                          * to Application */
 778                         rval = QLA_SUCCESS;
 779                         break;
 780 
 781                 case QL_DIAG_CMD_TEST_INT_LOOPBACK:
 782                 case QL_DIAG_CMD_TEST_EXT_LOOPBACK:
 783                         /* Execute diag test for Network */
 784                         qla4xxx_execute_diag_loopback_cmd(bsg_job);
 785                         /* Always return success as we want to sent bsg_reply
 786                          * to Application */
 787                         rval = QLA_SUCCESS;
 788                         break;
 789                 default:
 790                         ql4_printk(KERN_ERR, ha, "%s: Invalid diag test: 0x%x\n",
 791                                    __func__,
 792                                    bsg_req->rqst_data.h_vendor.vendor_cmd[2]);
 793                 }
 794         } else if ((diag_cmd == MBOX_CMD_SET_LED_CONFIG) ||
 795                    (diag_cmd == MBOX_CMD_GET_LED_CONFIG)) {
 796                 ql4xxx_execute_diag_cmd(bsg_job);
 797                 rval = QLA_SUCCESS;
 798         } else {
 799                 ql4_printk(KERN_ERR, ha, "%s: Invalid diag cmd: 0x%x\n",
 800                            __func__, diag_cmd);
 801         }
 802 
 803         return rval;
 804 }
 805 
 806 /**
 807  * qla4xxx_process_vendor_specific - handle vendor specific bsg request
 808  * @job: iscsi_bsg_job to handle
 809  **/
 810 int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job)
 811 {
 812         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
 813         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 814         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 815         struct scsi_qla_host *ha = to_qla_host(host);
 816 
 817         switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
 818         case QLISCSI_VND_READ_FLASH:
 819                 return qla4xxx_read_flash(bsg_job);
 820 
 821         case QLISCSI_VND_UPDATE_FLASH:
 822                 return qla4xxx_update_flash(bsg_job);
 823 
 824         case QLISCSI_VND_GET_ACB_STATE:
 825                 return qla4xxx_get_acb_state(bsg_job);
 826 
 827         case QLISCSI_VND_READ_NVRAM:
 828                 return qla4xxx_read_nvram(bsg_job);
 829 
 830         case QLISCSI_VND_UPDATE_NVRAM:
 831                 return qla4xxx_update_nvram(bsg_job);
 832 
 833         case QLISCSI_VND_RESTORE_DEFAULTS:
 834                 return qla4xxx_restore_defaults(bsg_job);
 835 
 836         case QLISCSI_VND_GET_ACB:
 837                 return qla4xxx_bsg_get_acb(bsg_job);
 838 
 839         case QLISCSI_VND_DIAG_TEST:
 840                 return qla4xxx_execute_diag_test(bsg_job);
 841 
 842         default:
 843                 ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: "
 844                            "0x%x\n", __func__, bsg_req->msgcode);
 845                 bsg_reply->result = (DID_ERROR << 16);
 846                 bsg_reply->reply_payload_rcv_len = 0;
 847                 bsg_job_done(bsg_job, bsg_reply->result,
 848                              bsg_reply->reply_payload_rcv_len);
 849                 return -ENOSYS;
 850         }
 851 }
 852 
 853 /**
 854  * qla4xxx_bsg_request - handle bsg request from ISCSI transport
 855  * @job: iscsi_bsg_job to handle
 856  */
 857 int qla4xxx_bsg_request(struct bsg_job *bsg_job)
 858 {
 859         struct iscsi_bsg_request *bsg_req = bsg_job->request;
 860         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
 861         struct scsi_qla_host *ha = to_qla_host(host);
 862 
 863         switch (bsg_req->msgcode) {
 864         case ISCSI_BSG_HST_VENDOR:
 865                 return qla4xxx_process_vendor_specific(bsg_job);
 866 
 867         default:
 868                 ql4_printk(KERN_ERR, ha, "%s: invalid BSG command: 0x%x\n",
 869                            __func__, bsg_req->msgcode);
 870         }
 871 
 872         return -ENOSYS;
 873 }

/* [<][>][^][v][top][bottom][index][help] */