aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c154
1 files changed, 137 insertions, 17 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b62836ddbbee..536cd5a80422 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6363,15 +6363,19 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
6363 ipr_cmd->scsi_cmd = scsi_cmd; 6363 ipr_cmd->scsi_cmd = scsi_cmd;
6364 ipr_cmd->done = ipr_scsi_eh_done; 6364 ipr_cmd->done = ipr_scsi_eh_done;
6365 6365
6366 if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) { 6366 if (ipr_is_gscsi(res)) {
6367 if (scsi_cmd->underflow == 0) 6367 if (scsi_cmd->underflow == 0)
6368 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; 6368 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
6369 6369
6370 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; 6370 if (res->reset_occurred) {
6371 if (ipr_is_gscsi(res) && res->reset_occurred) {
6372 res->reset_occurred = 0; 6371 res->reset_occurred = 0;
6373 ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_DELAY_AFTER_RST; 6372 ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_DELAY_AFTER_RST;
6374 } 6373 }
6374 }
6375
6376 if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
6377 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
6378
6375 ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_ALIGNED_BFR; 6379 ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_ALIGNED_BFR;
6376 if (scsi_cmd->flags & SCMD_TAGGED) 6380 if (scsi_cmd->flags & SCMD_TAGGED)
6377 ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_SIMPLE_TASK; 6381 ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_SIMPLE_TASK;
@@ -6502,7 +6506,6 @@ static struct scsi_host_template driver_template = {
6502 .shost_attrs = ipr_ioa_attrs, 6506 .shost_attrs = ipr_ioa_attrs,
6503 .sdev_attrs = ipr_dev_attrs, 6507 .sdev_attrs = ipr_dev_attrs,
6504 .proc_name = IPR_NAME, 6508 .proc_name = IPR_NAME,
6505 .use_blk_tags = 1,
6506}; 6509};
6507 6510
6508/** 6511/**
@@ -7671,6 +7674,63 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
7671 return IPR_RC_JOB_RETURN; 7674 return IPR_RC_JOB_RETURN;
7672} 7675}
7673 7676
7677static int ipr_ioa_service_action_failed(struct ipr_cmnd *ipr_cmd)
7678{
7679 u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
7680
7681 if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT)
7682 return IPR_RC_JOB_CONTINUE;
7683
7684 return ipr_reset_cmd_failed(ipr_cmd);
7685}
7686
7687static void ipr_build_ioa_service_action(struct ipr_cmnd *ipr_cmd,
7688 __be32 res_handle, u8 sa_code)
7689{
7690 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
7691
7692 ioarcb->res_handle = res_handle;
7693 ioarcb->cmd_pkt.cdb[0] = IPR_IOA_SERVICE_ACTION;
7694 ioarcb->cmd_pkt.cdb[1] = sa_code;
7695 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
7696}
7697
7698/**
7699 * ipr_ioafp_set_caching_parameters - Issue Set Cache parameters service
7700 * action
7701 *
7702 * Return value:
7703 * none
7704 **/
7705static int ipr_ioafp_set_caching_parameters(struct ipr_cmnd *ipr_cmd)
7706{
7707 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
7708 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
7709 struct ipr_inquiry_pageC4 *pageC4 = &ioa_cfg->vpd_cbs->pageC4_data;
7710
7711 ENTER;
7712
7713 ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg;
7714
7715 if (pageC4->cache_cap[0] & IPR_CAP_SYNC_CACHE) {
7716 ipr_build_ioa_service_action(ipr_cmd,
7717 cpu_to_be32(IPR_IOA_RES_HANDLE),
7718 IPR_IOA_SA_CHANGE_CACHE_PARAMS);
7719
7720 ioarcb->cmd_pkt.cdb[2] = 0x40;
7721
7722 ipr_cmd->job_step_failed = ipr_ioa_service_action_failed;
7723 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
7724 IPR_SET_SUP_DEVICE_TIMEOUT);
7725
7726 LEAVE;
7727 return IPR_RC_JOB_RETURN;
7728 }
7729
7730 LEAVE;
7731 return IPR_RC_JOB_CONTINUE;
7732}
7733
7674/** 7734/**
7675 * ipr_ioafp_inquiry - Send an Inquiry to the adapter. 7735 * ipr_ioafp_inquiry - Send an Inquiry to the adapter.
7676 * @ipr_cmd: ipr command struct 7736 * @ipr_cmd: ipr command struct
@@ -7722,6 +7782,39 @@ static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page)
7722} 7782}
7723 7783
7724/** 7784/**
7785 * ipr_ioafp_pageC4_inquiry - Send a Page 0xC4 Inquiry to the adapter.
7786 * @ipr_cmd: ipr command struct
7787 *
7788 * This function sends a Page 0xC4 inquiry to the adapter
7789 * to retrieve software VPD information.
7790 *
7791 * Return value:
7792 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
7793 **/
7794static int ipr_ioafp_pageC4_inquiry(struct ipr_cmnd *ipr_cmd)
7795{
7796 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
7797 struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
7798 struct ipr_inquiry_pageC4 *pageC4 = &ioa_cfg->vpd_cbs->pageC4_data;
7799
7800 ENTER;
7801 ipr_cmd->job_step = ipr_ioafp_set_caching_parameters;
7802 memset(pageC4, 0, sizeof(*pageC4));
7803
7804 if (ipr_inquiry_page_supported(page0, 0xC4)) {
7805 ipr_ioafp_inquiry(ipr_cmd, 1, 0xC4,
7806 (ioa_cfg->vpd_cbs_dma
7807 + offsetof(struct ipr_misc_cbs,
7808 pageC4_data)),
7809 sizeof(struct ipr_inquiry_pageC4));
7810 return IPR_RC_JOB_RETURN;
7811 }
7812
7813 LEAVE;
7814 return IPR_RC_JOB_CONTINUE;
7815}
7816
7817/**
7725 * ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter. 7818 * ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter.
7726 * @ipr_cmd: ipr command struct 7819 * @ipr_cmd: ipr command struct
7727 * 7820 *
@@ -7738,7 +7831,7 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd)
7738 struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; 7831 struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap;
7739 7832
7740 ENTER; 7833 ENTER;
7741 ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; 7834 ipr_cmd->job_step = ipr_ioafp_pageC4_inquiry;
7742 memset(cap, 0, sizeof(*cap)); 7835 memset(cap, 0, sizeof(*cap));
7743 7836
7744 if (ipr_inquiry_page_supported(page0, 0xD0)) { 7837 if (ipr_inquiry_page_supported(page0, 0xD0)) {
@@ -8277,6 +8370,42 @@ static int ipr_reset_get_unit_check_job(struct ipr_cmnd *ipr_cmd)
8277 return IPR_RC_JOB_RETURN; 8370 return IPR_RC_JOB_RETURN;
8278} 8371}
8279 8372
8373static int ipr_dump_mailbox_wait(struct ipr_cmnd *ipr_cmd)
8374{
8375 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
8376
8377 ENTER;
8378
8379 if (ioa_cfg->sdt_state != GET_DUMP)
8380 return IPR_RC_JOB_RETURN;
8381
8382 if (!ioa_cfg->sis64 || !ipr_cmd->u.time_left ||
8383 (readl(ioa_cfg->regs.sense_interrupt_reg) &
8384 IPR_PCII_MAILBOX_STABLE)) {
8385
8386 if (!ipr_cmd->u.time_left)
8387 dev_err(&ioa_cfg->pdev->dev,
8388 "Timed out waiting for Mailbox register.\n");
8389
8390 ioa_cfg->sdt_state = READ_DUMP;
8391 ioa_cfg->dump_timeout = 0;
8392 if (ioa_cfg->sis64)
8393 ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
8394 else
8395 ipr_reset_start_timer(ipr_cmd, IPR_SIS32_DUMP_TIMEOUT);
8396 ipr_cmd->job_step = ipr_reset_wait_for_dump;
8397 schedule_work(&ioa_cfg->work_q);
8398
8399 } else {
8400 ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
8401 ipr_reset_start_timer(ipr_cmd,
8402 IPR_CHECK_FOR_RESET_TIMEOUT);
8403 }
8404
8405 LEAVE;
8406 return IPR_RC_JOB_RETURN;
8407}
8408
8280/** 8409/**
8281 * ipr_reset_restore_cfg_space - Restore PCI config space. 8410 * ipr_reset_restore_cfg_space - Restore PCI config space.
8282 * @ipr_cmd: ipr command struct 8411 * @ipr_cmd: ipr command struct
@@ -8326,20 +8455,11 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
8326 8455
8327 if (ioa_cfg->in_ioa_bringdown) { 8456 if (ioa_cfg->in_ioa_bringdown) {
8328 ipr_cmd->job_step = ipr_ioa_bringdown_done; 8457 ipr_cmd->job_step = ipr_ioa_bringdown_done;
8458 } else if (ioa_cfg->sdt_state == GET_DUMP) {
8459 ipr_cmd->job_step = ipr_dump_mailbox_wait;
8460 ipr_cmd->u.time_left = IPR_WAIT_FOR_MAILBOX;
8329 } else { 8461 } else {
8330 ipr_cmd->job_step = ipr_reset_enable_ioa; 8462 ipr_cmd->job_step = ipr_reset_enable_ioa;
8331
8332 if (GET_DUMP == ioa_cfg->sdt_state) {
8333 ioa_cfg->sdt_state = READ_DUMP;
8334 ioa_cfg->dump_timeout = 0;
8335 if (ioa_cfg->sis64)
8336 ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
8337 else
8338 ipr_reset_start_timer(ipr_cmd, IPR_SIS32_DUMP_TIMEOUT);
8339 ipr_cmd->job_step = ipr_reset_wait_for_dump;
8340 schedule_work(&ioa_cfg->work_q);
8341 return IPR_RC_JOB_RETURN;
8342 }
8343 } 8463 }
8344 8464
8345 LEAVE; 8465 LEAVE;