summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c131
1 files changed, 74 insertions, 57 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 735402f61aba..8c2f4c4041c1 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -567,7 +567,8 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
- struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
+ struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa;
+ struct ipr_ioasa64 *ioasa64 = &ipr_cmd->s.ioasa64;
dma_addr_t dma_addr = ipr_cmd->dma_addr;
memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
@@ -576,19 +577,19 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
ioarcb->ioadl_len = 0;
ioarcb->read_ioadl_len = 0;
- if (ipr_cmd->ioa_cfg->sis64)
+ if (ipr_cmd->ioa_cfg->sis64) {
ioarcb->u.sis64_addr_data.data_ioadl_addr =
cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
- else {
+ ioasa64->u.gata.status = 0;
+ } else {
ioarcb->write_ioadl_addr =
cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+ ioasa->u.gata.status = 0;
}
- ioasa->ioasc = 0;
- ioasa->residual_data_len = 0;
- ioasa->u.gata.status = 0;
-
+ ioasa->hdr.ioasc = 0;
+ ioasa->hdr.residual_data_len = 0;
ipr_cmd->scsi_cmd = NULL;
ipr_cmd->qc = NULL;
ipr_cmd->sense_buffer[0] = 0;
@@ -768,8 +769,8 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
list_for_each_entry_safe(ipr_cmd, temp, &ioa_cfg->pending_q, queue) {
list_del(&ipr_cmd->queue);
- ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_IOA_WAS_RESET);
- ipr_cmd->ioasa.ilid = cpu_to_be32(IPR_DRIVER_ILID);
+ ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_IOA_WAS_RESET);
+ ipr_cmd->s.ioasa.hdr.ilid = cpu_to_be32(IPR_DRIVER_ILID);
if (ipr_cmd->scsi_cmd)
ipr_cmd->done = ipr_scsi_eh_done;
@@ -1319,7 +1320,7 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
list_del(&hostrcb->queue);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
@@ -2354,7 +2355,7 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
u32 fd_ioasc;
if (ioa_cfg->sis64)
@@ -4509,11 +4510,16 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
}
ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
- ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
- if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET)
- memcpy(&res->sata_port->ioasa, &ipr_cmd->ioasa.u.gata,
- sizeof(struct ipr_ioasa_gata));
+ if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET) {
+ if (ipr_cmd->ioa_cfg->sis64)
+ memcpy(&res->sata_port->ioasa, &ipr_cmd->s.ioasa64.u.gata,
+ sizeof(struct ipr_ioasa_gata));
+ else
+ memcpy(&res->sata_port->ioasa, &ipr_cmd->s.ioasa.u.gata,
+ sizeof(struct ipr_ioasa_gata));
+ }
LEAVE;
return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0);
@@ -4768,7 +4774,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
scmd_printk(KERN_ERR, scsi_cmd, "Aborting command: %02X\n",
scsi_cmd->cmnd[0]);
ipr_send_blocking_cmd(ipr_cmd, ipr_abort_timeout, IPR_CANCEL_ALL_TIMEOUT);
- ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
/*
* If the abort task timed out and we sent a bus reset, we will get
@@ -4940,7 +4946,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
ipr_cmd = ioa_cfg->ipr_cmnd_list[cmd_index];
- ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, ioasc);
@@ -5137,7 +5143,7 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd)
struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
struct ipr_resource_entry *res = scsi_cmd->device->hostdata;
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
if (IPR_IOASC_SENSE_KEY(ioasc) > 0) {
scsi_cmd->result |= (DID_ERROR << 16);
@@ -5168,7 +5174,7 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd)
static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
- struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
+ struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa;
dma_addr_t dma_addr = ipr_cmd->dma_addr;
memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
@@ -5176,8 +5182,8 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
ioarcb->read_data_transfer_length = 0;
ioarcb->ioadl_len = 0;
ioarcb->read_ioadl_len = 0;
- ioasa->ioasc = 0;
- ioasa->residual_data_len = 0;
+ ioasa->hdr.ioasc = 0;
+ ioasa->hdr.residual_data_len = 0;
if (ipr_cmd->ioa_cfg->sis64)
ioarcb->u.sis64_addr_data.data_ioadl_addr =
@@ -5202,7 +5208,7 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd)
{
struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
if (IPR_IOASC_SENSE_KEY(ioasc) > 0) {
ipr_erp_done(ipr_cmd);
@@ -5279,12 +5285,12 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg,
int i;
u16 data_len;
u32 ioasc, fd_ioasc;
- struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
+ struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa;
__be32 *ioasa_data = (__be32 *)ioasa;
int error_index;
- ioasc = be32_to_cpu(ioasa->ioasc) & IPR_IOASC_IOASC_MASK;
- fd_ioasc = be32_to_cpu(ioasa->fd_ioasc) & IPR_IOASC_IOASC_MASK;
+ ioasc = be32_to_cpu(ioasa->hdr.ioasc) & IPR_IOASC_IOASC_MASK;
+ fd_ioasc = be32_to_cpu(ioasa->hdr.fd_ioasc) & IPR_IOASC_IOASC_MASK;
if (0 == ioasc)
return;
@@ -5299,7 +5305,7 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg,
if (ioa_cfg->log_level < IPR_MAX_LOG_LEVEL) {
/* Don't log an error if the IOA already logged one */
- if (ioasa->ilid != 0)
+ if (ioasa->hdr.ilid != 0)
return;
if (!ipr_is_gscsi(res))
@@ -5311,10 +5317,11 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg,
ipr_res_err(ioa_cfg, res, "%s\n", ipr_error_table[error_index].error);
- if (sizeof(struct ipr_ioasa) < be16_to_cpu(ioasa->ret_stat_len))
+ data_len = be16_to_cpu(ioasa->hdr.ret_stat_len);
+ if (ioa_cfg->sis64 && sizeof(struct ipr_ioasa64) < data_len)
+ data_len = sizeof(struct ipr_ioasa64);
+ else if (!ioa_cfg->sis64 && sizeof(struct ipr_ioasa) < data_len)
data_len = sizeof(struct ipr_ioasa);
- else
- data_len = be16_to_cpu(ioasa->ret_stat_len);
ipr_err("IOASA Dump:\n");
@@ -5340,8 +5347,8 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd)
u32 failing_lba;
u8 *sense_buf = ipr_cmd->scsi_cmd->sense_buffer;
struct ipr_resource_entry *res = ipr_cmd->scsi_cmd->device->hostdata;
- struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
- u32 ioasc = be32_to_cpu(ioasa->ioasc);
+ struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa;
+ u32 ioasc = be32_to_cpu(ioasa->hdr.ioasc);
memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
@@ -5384,7 +5391,7 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd)
/* Illegal request */
if ((IPR_IOASC_SENSE_KEY(ioasc) == 0x05) &&
- (be32_to_cpu(ioasa->ioasc_specific) & IPR_FIELD_POINTER_VALID)) {
+ (be32_to_cpu(ioasa->hdr.ioasc_specific) & IPR_FIELD_POINTER_VALID)) {
sense_buf[7] = 10; /* additional length */
/* IOARCB was in error */
@@ -5395,10 +5402,10 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd)
sense_buf[16] =
((IPR_FIELD_POINTER_MASK &
- be32_to_cpu(ioasa->ioasc_specific)) >> 8) & 0xff;
+ be32_to_cpu(ioasa->hdr.ioasc_specific)) >> 8) & 0xff;
sense_buf[17] =
(IPR_FIELD_POINTER_MASK &
- be32_to_cpu(ioasa->ioasc_specific)) & 0xff;
+ be32_to_cpu(ioasa->hdr.ioasc_specific)) & 0xff;
} else {
if (ioasc == IPR_IOASC_MED_DO_NOT_REALLOC) {
if (ipr_is_vset_device(res))
@@ -5430,14 +5437,20 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd)
**/
static int ipr_get_autosense(struct ipr_cmnd *ipr_cmd)
{
- struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
+ struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa;
+ struct ipr_ioasa64 *ioasa64 = &ipr_cmd->s.ioasa64;
- if ((be32_to_cpu(ioasa->ioasc_specific) & IPR_AUTOSENSE_VALID) == 0)
+ if ((be32_to_cpu(ioasa->hdr.ioasc_specific) & IPR_AUTOSENSE_VALID) == 0)
return 0;
- memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data,
- min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len),
- SCSI_SENSE_BUFFERSIZE));
+ if (ipr_cmd->ioa_cfg->sis64)
+ memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa64->auto_sense.data,
+ min_t(u16, be16_to_cpu(ioasa64->auto_sense.auto_sense_len),
+ SCSI_SENSE_BUFFERSIZE));
+ else
+ memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data,
+ min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len),
+ SCSI_SENSE_BUFFERSIZE));
return 1;
}
@@ -5457,7 +5470,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
{
struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
struct ipr_resource_entry *res = scsi_cmd->device->hostdata;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
u32 masked_ioasc = ioasc & IPR_IOASC_IOASC_MASK;
if (!res) {
@@ -5549,9 +5562,9 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
- scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->ioasa.residual_data_len));
+ scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len));
if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) {
scsi_dma_unmap(ipr_cmd->scsi_cmd);
@@ -5841,19 +5854,23 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
struct ata_queued_cmd *qc = ipr_cmd->qc;
struct ipr_sata_port *sata_port = qc->ap->private_data;
struct ipr_resource_entry *res = sata_port->res;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
- memcpy(&sata_port->ioasa, &ipr_cmd->ioasa.u.gata,
- sizeof(struct ipr_ioasa_gata));
+ if (ipr_cmd->ioa_cfg->sis64)
+ memcpy(&sata_port->ioasa, &ipr_cmd->s.ioasa64.u.gata,
+ sizeof(struct ipr_ioasa_gata));
+ else
+ memcpy(&sata_port->ioasa, &ipr_cmd->s.ioasa.u.gata,
+ sizeof(struct ipr_ioasa_gata));
ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
- if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
+ if (be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
scsi_report_device_reset(ioa_cfg->host, res->bus, res->target);
if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
- qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);
+ qc->err_mask |= __ac_err_mask(sata_port->ioasa.status);
else
- qc->err_mask |= ac_err_mask(ipr_cmd->ioasa.u.gata.status);
+ qc->err_mask |= ac_err_mask(sata_port->ioasa.status);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
ata_qc_complete(qc);
}
@@ -6522,7 +6539,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
dev_err(&ioa_cfg->pdev->dev,
"0x%02X failed with IOASC: 0x%08X\n",
@@ -6546,7 +6563,7 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd)
static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
ipr_cmd->job_step = ipr_set_supported_devs;
@@ -6636,7 +6653,7 @@ static int ipr_ioafp_mode_select_page24(struct ipr_cmnd *ipr_cmd)
**/
static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd)
{
- u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
ipr_cmd->job_step = ipr_ioafp_mode_sense_page28;
@@ -7337,12 +7354,12 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
rc = pci_restore_state(ioa_cfg->pdev);
if (rc != PCIBIOS_SUCCESSFUL) {
- ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
+ ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
return IPR_RC_JOB_CONTINUE;
}
if (ipr_set_pcix_cmd_reg(ioa_cfg)) {
- ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
+ ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
return IPR_RC_JOB_CONTINUE;
}
@@ -7411,7 +7428,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
if (rc != PCIBIOS_SUCCESSFUL) {
pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
- ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
+ ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
rc = IPR_RC_JOB_CONTINUE;
} else {
ipr_cmd->job_step = ipr_reset_bist_done;
@@ -7670,7 +7687,7 @@ static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd)
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
do {
- ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+ ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
if (ioa_cfg->reset_cmd != ipr_cmd) {
/*
@@ -8053,13 +8070,13 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
ioarcb->u.sis64_addr_data.data_ioadl_addr =
cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
ioarcb->u.sis64_addr_data.ioasa_host_pci_addr =
- cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+ cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, s.ioasa64));
} else {
ioarcb->write_ioadl_addr =
cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
ioarcb->ioasa_host_pci_addr =
- cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+ cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, s.ioasa));
}
ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa));
ipr_cmd->cmd_index = i;
OpenPOWER on IntegriCloud