diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 238 |
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) | |||
408 | void | 411 | void |
409 | qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor, | 412 | qla2x00_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 | |||
3231 | int | ||
3232 | qla81xx_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 | |||
3262 | int | ||
3263 | qla81xx_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 | |||
3293 | int | ||
3294 | qla81xx_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 | |||
3328 | int | ||
3329 | qla81xx_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 | |||
3354 | int | ||
3355 | qla2x00_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 | |||
3393 | int | ||
3394 | qla2x00_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 | } | ||