diff options
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r-- | drivers/scsi/ipr.c | 230 |
1 files changed, 129 insertions, 101 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b90c118119d..82ea4a8226b 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; @@ -1040,7 +1041,7 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res, proto = cfgtew->u.cfgte64->proto; res->res_flags = cfgtew->u.cfgte64->res_flags; res->qmodel = IPR_QUEUEING_MODEL64(res); - res->type = cfgtew->u.cfgte64->res_type & 0x0f; + res->type = cfgtew->u.cfgte64->res_type; memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, sizeof(res->res_path)); @@ -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) @@ -3120,6 +3121,7 @@ restart: #ifdef CONFIG_SCSI_IPR_TRACE /** * ipr_read_trace - Dump the adapter trace + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3129,7 +3131,7 @@ restart: * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_read_trace(struct kobject *kobj, +static ssize_t ipr_read_trace(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -3764,6 +3766,7 @@ static struct device_attribute *ipr_ioa_attrs[] = { #ifdef CONFIG_SCSI_IPR_DUMP /** * ipr_read_dump - Dump the adapter + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3773,7 +3776,7 @@ static struct device_attribute *ipr_ioa_attrs[] = { * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_read_dump(struct kobject *kobj, +static ssize_t ipr_read_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -3927,6 +3930,7 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) /** * ipr_write_dump - Setup dump state of adapter + * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer @@ -3936,7 +3940,7 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) * Return value: * number of bytes printed to buffer **/ -static ssize_t ipr_write_dump(struct kobject *kobj, +static ssize_t ipr_write_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -4506,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); @@ -4765,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 @@ -4809,15 +4818,39 @@ static int ipr_eh_abort(struct scsi_cmnd * scsi_cmd) /** * ipr_handle_other_interrupt - Handle "other" interrupts * @ioa_cfg: ioa config struct - * @int_reg: interrupt register * * Return value: * IRQ_NONE / IRQ_HANDLED **/ -static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg, - volatile u32 int_reg) +static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg) { irqreturn_t rc = IRQ_HANDLED; + volatile u32 int_reg, int_mask_reg; + + int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; + + /* If an interrupt on the adapter did not occur, ignore it. + * Or in the case of SIS 64, check for a stage change interrupt. + */ + if ((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0) { + if (ioa_cfg->sis64) { + int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { + + /* clear stage change */ + writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + list_del(&ioa_cfg->reset_cmd->queue); + del_timer(&ioa_cfg->reset_cmd->timer); + ipr_reset_ioa_job(ioa_cfg->reset_cmd); + return IRQ_HANDLED; + } + } + + return IRQ_NONE; + } if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { /* Mask the interrupt */ @@ -4878,7 +4911,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) { struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp; unsigned long lock_flags = 0; - volatile u32 int_reg, int_mask_reg; + volatile u32 int_reg; u32 ioasc; u16 cmd_index; int num_hrrq = 0; @@ -4893,33 +4926,6 @@ static irqreturn_t ipr_isr(int irq, void *devp) return IRQ_NONE; } - int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; - - /* If an interrupt on the adapter did not occur, ignore it. - * Or in the case of SIS 64, check for a stage change interrupt. - */ - if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { - if (ioa_cfg->sis64) { - int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; - if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { - - /* clear stage change */ - writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; - list_del(&ioa_cfg->reset_cmd->queue); - del_timer(&ioa_cfg->reset_cmd->timer); - ipr_reset_ioa_job(ioa_cfg->reset_cmd); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return IRQ_HANDLED; - } - } - - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return IRQ_NONE; - } - while (1) { ipr_cmd = NULL; @@ -4937,7 +4943,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); @@ -4959,7 +4965,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) /* Clear the PCI interrupt */ do { writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); } while (int_reg & IPR_PCII_HRRQ_UPDATED && num_hrrq++ < IPR_MAX_HRRQ_RETRIES); @@ -4974,7 +4980,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) } if (unlikely(rc == IRQ_NONE)) - rc = ipr_handle_other_interrupt(ioa_cfg, int_reg); + rc = ipr_handle_other_interrupt(ioa_cfg); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return rc; @@ -5011,6 +5017,10 @@ static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg, ipr_cmd->dma_use_sg = nseg; + ioarcb->data_transfer_length = cpu_to_be32(length); + ioarcb->ioadl_len = + cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); + if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { ioadl_flags = IPR_IOADL_FLAGS_WRITE; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; @@ -5132,7 +5142,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); @@ -5163,7 +5173,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)); @@ -5171,8 +5181,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 = @@ -5197,7 +5207,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); @@ -5274,12 +5284,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; @@ -5294,7 +5304,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)) @@ -5306,10 +5316,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"); @@ -5335,8 +5346,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); @@ -5379,7 +5390,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 */ @@ -5390,10 +5401,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)) @@ -5425,14 +5436,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; } @@ -5452,7 +5469,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) { @@ -5544,9 +5561,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); @@ -5836,19 +5853,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); } @@ -6517,7 +6538,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", @@ -6541,7 +6562,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; @@ -6631,7 +6652,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; @@ -6703,7 +6724,7 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) list_move_tail(&res->queue, &old_res); if (ioa_cfg->sis64) - entries = ioa_cfg->u.cfg_table64->hdr64.num_entries; + entries = be16_to_cpu(ioa_cfg->u.cfg_table64->hdr64.num_entries); else entries = ioa_cfg->u.cfg_table->hdr.num_entries; @@ -6789,6 +6810,7 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; + ioarcb->cmd_pkt.cdb[6] = (ioa_cfg->cfg_table_size >> 16) & 0xff; ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff; ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff; @@ -7119,7 +7141,9 @@ static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd) ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time); /* sanity check the stage_time value */ - if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) + if (stage_time == 0) + stage_time = IPR_IPL_INIT_DEFAULT_STAGE_TIME; + else if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) stage_time = IPR_IPL_INIT_MIN_STAGE_TIME; else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT) stage_time = IPR_LONG_OPERATIONAL_TIMEOUT; @@ -7162,13 +7186,14 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; volatile u32 int_reg; + volatile u64 maskval; ENTER; ipr_cmd->job_step = ipr_ioafp_identify_hrrq; ipr_init_ioa_mem(ioa_cfg); ioa_cfg->allow_interrupts = 1; - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), @@ -7180,9 +7205,12 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) /* Enable destructive diagnostics on IOA */ writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32); - writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); - if (ioa_cfg->sis64) - writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg); + if (ioa_cfg->sis64) { + maskval = IPR_PCII_IPL_STAGE_CHANGE; + maskval = (maskval << 32) | IPR_PCII_OPER_INTERRUPTS; + writeq(maskval, ioa_cfg->regs.clr_interrupt_mask_reg); + } else + writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); @@ -7329,12 +7357,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; } @@ -7361,7 +7389,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) } } - ENTER; + LEAVE; return IPR_RC_JOB_CONTINUE; } @@ -7403,7 +7431,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; @@ -7662,7 +7690,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) { /* @@ -8045,13 +8073,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; |