aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_mbx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c238
1 files changed, 224 insertions, 14 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 4aab7acf7525..e67c1660bf46 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -45,6 +45,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
45 struct qla_hw_data *ha = vha->hw; 45 struct qla_hw_data *ha = vha->hw;
46 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 46 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
47 47
48 if (ha->pdev->error_state > pci_channel_io_frozen)
49 return QLA_FUNCTION_TIMEOUT;
50
48 reg = ha->iobase; 51 reg = ha->iobase;
49 io_lock_on = base_vha->flags.init_done; 52 io_lock_on = base_vha->flags.init_done;
50 53
@@ -408,7 +411,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
408void 411void
409qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor, 412qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
410 uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi, 413 uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
411 uint32_t *mpi_caps) 414 uint32_t *mpi_caps, uint8_t *phy)
412{ 415{
413 int rval; 416 int rval;
414 mbx_cmd_t mc; 417 mbx_cmd_t mc;
@@ -420,7 +423,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
420 mcp->out_mb = MBX_0; 423 mcp->out_mb = MBX_0;
421 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 424 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
422 if (IS_QLA81XX(vha->hw)) 425 if (IS_QLA81XX(vha->hw))
423 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; 426 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
424 mcp->flags = 0; 427 mcp->flags = 0;
425 mcp->tov = MBX_TOV_SECONDS; 428 mcp->tov = MBX_TOV_SECONDS;
426 rval = qla2x00_mailbox_command(vha, mcp); 429 rval = qla2x00_mailbox_command(vha, mcp);
@@ -435,11 +438,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
435 else 438 else
436 *memory = (mcp->mb[5] << 16) | mcp->mb[4]; 439 *memory = (mcp->mb[5] << 16) | mcp->mb[4];
437 if (IS_QLA81XX(vha->hw)) { 440 if (IS_QLA81XX(vha->hw)) {
438 mpi[0] = mcp->mb[10] >> 8; 441 mpi[0] = mcp->mb[10] & 0xff;
439 mpi[1] = mcp->mb[10] & 0xff; 442 mpi[1] = mcp->mb[11] >> 8;
440 mpi[2] = mcp->mb[11] >> 8; 443 mpi[2] = mcp->mb[11] & 0xff;
441 mpi[3] = mcp->mb[11] & 0xff;
442 *mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13]; 444 *mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
445 phy[0] = mcp->mb[8] & 0xff;
446 phy[1] = mcp->mb[9] >> 8;
447 phy[2] = mcp->mb[9] & 0xff;
443 } 448 }
444 449
445 if (rval != QLA_SUCCESS) { 450 if (rval != QLA_SUCCESS) {
@@ -1043,14 +1048,22 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
1043 else 1048 else
1044 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; 1049 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1045 1050
1051 mcp->mb[1] = 0;
1046 mcp->mb[2] = MSW(ha->init_cb_dma); 1052 mcp->mb[2] = MSW(ha->init_cb_dma);
1047 mcp->mb[3] = LSW(ha->init_cb_dma); 1053 mcp->mb[3] = LSW(ha->init_cb_dma);
1048 mcp->mb[4] = 0;
1049 mcp->mb[5] = 0;
1050 mcp->mb[6] = MSW(MSD(ha->init_cb_dma)); 1054 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1051 mcp->mb[7] = LSW(MSD(ha->init_cb_dma)); 1055 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
1052 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1056 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1053 mcp->in_mb = MBX_5|MBX_4|MBX_0; 1057 if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
1058 mcp->mb[1] = BIT_0;
1059 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1060 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1061 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1062 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1063 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1064 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1065 }
1066 mcp->in_mb = MBX_0;
1054 mcp->buf_size = size; 1067 mcp->buf_size = size;
1055 mcp->flags = MBX_DMA_OUT; 1068 mcp->flags = MBX_DMA_OUT;
1056 mcp->tov = MBX_TOV_SECONDS; 1069 mcp->tov = MBX_TOV_SECONDS;
@@ -1187,10 +1200,6 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
1187 fcport->d_id.b.al_pa = pd->port_id[2]; 1200 fcport->d_id.b.al_pa = pd->port_id[2];
1188 fcport->d_id.b.rsvd_1 = 0; 1201 fcport->d_id.b.rsvd_1 = 0;
1189 1202
1190 /* Check for device require authentication. */
1191 pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
1192 (fcport->flags &= ~FCF_AUTH_REQ);
1193
1194 /* If not target must be initiator or unknown type. */ 1203 /* If not target must be initiator or unknown type. */
1195 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 1204 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1196 fcport->port_type = FCT_INITIATOR; 1205 fcport->port_type = FCT_INITIATOR;
@@ -3218,3 +3227,204 @@ qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3218 3227
3219 return rval; 3228 return rval;
3220} 3229}
3230
3231int
3232qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3233{
3234 int rval;
3235 mbx_cmd_t mc;
3236 mbx_cmd_t *mcp = &mc;
3237
3238 if (!IS_QLA81XX(vha->hw))
3239 return QLA_FUNCTION_FAILED;
3240
3241 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3242
3243 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3244 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3245 mcp->out_mb = MBX_1|MBX_0;
3246 mcp->in_mb = MBX_1|MBX_0;
3247 mcp->tov = MBX_TOV_SECONDS;
3248 mcp->flags = 0;
3249 rval = qla2x00_mailbox_command(vha, mcp);
3250
3251 if (rval != QLA_SUCCESS) {
3252 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
3253 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
3254 } else {
3255 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3256 *sector_size = mcp->mb[1];
3257 }
3258
3259 return rval;
3260}
3261
3262int
3263qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3264{
3265 int rval;
3266 mbx_cmd_t mc;
3267 mbx_cmd_t *mcp = &mc;
3268
3269 if (!IS_QLA81XX(vha->hw))
3270 return QLA_FUNCTION_FAILED;
3271
3272 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3273
3274 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3275 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3276 FAC_OPT_CMD_WRITE_PROTECT;
3277 mcp->out_mb = MBX_1|MBX_0;
3278 mcp->in_mb = MBX_1|MBX_0;
3279 mcp->tov = MBX_TOV_SECONDS;
3280 mcp->flags = 0;
3281 rval = qla2x00_mailbox_command(vha, mcp);
3282
3283 if (rval != QLA_SUCCESS) {
3284 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
3285 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
3286 } else {
3287 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3288 }
3289
3290 return rval;
3291}
3292
3293int
3294qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3295{
3296 int rval;
3297 mbx_cmd_t mc;
3298 mbx_cmd_t *mcp = &mc;
3299
3300 if (!IS_QLA81XX(vha->hw))
3301 return QLA_FUNCTION_FAILED;
3302
3303 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3304
3305 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3306 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3307 mcp->mb[2] = LSW(start);
3308 mcp->mb[3] = MSW(start);
3309 mcp->mb[4] = LSW(finish);
3310 mcp->mb[5] = MSW(finish);
3311 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3312 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3313 mcp->tov = MBX_TOV_SECONDS;
3314 mcp->flags = 0;
3315 rval = qla2x00_mailbox_command(vha, mcp);
3316
3317 if (rval != QLA_SUCCESS) {
3318 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
3319 "mb[2]=%x.\n", __func__, vha->host_no, rval, mcp->mb[0],
3320 mcp->mb[1], mcp->mb[2]));
3321 } else {
3322 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3323 }
3324
3325 return rval;
3326}
3327
3328int
3329qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3330{
3331 int rval = 0;
3332 mbx_cmd_t mc;
3333 mbx_cmd_t *mcp = &mc;
3334
3335 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3336
3337 mcp->mb[0] = MBC_RESTART_MPI_FW;
3338 mcp->out_mb = MBX_0;
3339 mcp->in_mb = MBX_0|MBX_1;
3340 mcp->tov = MBX_TOV_SECONDS;
3341 mcp->flags = 0;
3342 rval = qla2x00_mailbox_command(vha, mcp);
3343
3344 if (rval != QLA_SUCCESS) {
3345 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=0x%x mb[1]=0x%x.\n",
3346 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
3347 } else {
3348 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3349 }
3350
3351 return rval;
3352}
3353
3354int
3355qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
3356 dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
3357{
3358 int rval;
3359 mbx_cmd_t mc;
3360 mbx_cmd_t *mcp = &mc;
3361
3362 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3363
3364 mcp->mb[0] = MBC_READ_SFP;
3365 mcp->mb[1] = dev;
3366 mcp->mb[2] = MSW(sfp_dma);
3367 mcp->mb[3] = LSW(sfp_dma);
3368 mcp->mb[6] = MSW(MSD(sfp_dma));
3369 mcp->mb[7] = LSW(MSD(sfp_dma));
3370 mcp->mb[8] = len;
3371 mcp->mb[9] = adr;
3372 mcp->mb[10] = opt;
3373 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3374 mcp->in_mb = MBX_0;
3375 mcp->tov = MBX_TOV_SECONDS;
3376 mcp->flags = 0;
3377 rval = qla2x00_mailbox_command(vha, mcp);
3378
3379 if (opt & BIT_0)
3380 if (sfp)
3381 *sfp = mcp->mb[8];
3382
3383 if (rval != QLA_SUCCESS) {
3384 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
3385 vha->host_no, rval, mcp->mb[0]));
3386 } else {
3387 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
3388 }
3389
3390 return rval;
3391}
3392
3393int
3394qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
3395 dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
3396{
3397 int rval;
3398 mbx_cmd_t mc;
3399 mbx_cmd_t *mcp = &mc;
3400
3401 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3402
3403 if (opt & BIT_0)
3404 if (sfp)
3405 len = *sfp;
3406
3407 mcp->mb[0] = MBC_WRITE_SFP;
3408 mcp->mb[1] = dev;
3409 mcp->mb[2] = MSW(sfp_dma);
3410 mcp->mb[3] = LSW(sfp_dma);
3411 mcp->mb[6] = MSW(MSD(sfp_dma));
3412 mcp->mb[7] = LSW(MSD(sfp_dma));
3413 mcp->mb[8] = len;
3414 mcp->mb[9] = adr;
3415 mcp->mb[10] = opt;
3416 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3417 mcp->in_mb = MBX_0;
3418 mcp->tov = MBX_TOV_SECONDS;
3419 mcp->flags = 0;
3420 rval = qla2x00_mailbox_command(vha, mcp);
3421
3422 if (rval != QLA_SUCCESS) {
3423 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
3424 vha->host_no, rval, mcp->mb[0]));
3425 } else {
3426 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3427 }
3428
3429 return rval;
3430}