From 1121b794a384bc317fe36e967b82308b0e2c3852 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 29 Mar 2006 09:37:16 -0600 Subject: [SCSI] ipr: Disk remove path cleanup Instead of NULLing the resource entry pointer when a disk goes away to prevent any new commands being sent to it, set the adapter resource handle to an invalid value so new ops getting sent to it will fail with a selection timeout response. This patch is needed for future SATA patches. Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/scsi/ipr.c') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 5890e5f92d8..154b78c5baa 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -869,8 +869,8 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { if (res->sdev) { - res->sdev->hostdata = NULL; res->del_from_ml = 1; + res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; if (ioa_cfg->allow_ml_add_del) schedule_work(&ioa_cfg->work_q); } else @@ -2107,7 +2107,6 @@ restart: did_work = 1; sdev = res->sdev; if (!scsi_device_get(sdev)) { - res->sdev = NULL; list_move_tail(&res->queue, &ioa_cfg->free_res_q); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); scsi_remove_device(sdev); @@ -2124,6 +2123,7 @@ restart: bus = res->cfgte.res_addr.bus; target = res->cfgte.res_addr.target; lun = res->cfgte.res_addr.lun; + res->add_to_ml = 0; spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); scsi_add_device(ioa_cfg->host, bus, target, lun); spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); @@ -4980,7 +4980,7 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) list_for_each_entry_safe(res, temp, &old_res, queue) { if (res->sdev) { res->del_from_ml = 1; - res->sdev->hostdata = NULL; + res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; list_move_tail(&res->queue, &ioa_cfg->used_res_q); } else { list_move_tail(&res->queue, &ioa_cfg->free_res_q); -- cgit v1.2.3 From e4fbf44ed0618acce4a06010ed9fa9c02e06e36a Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 29 Mar 2006 09:37:22 -0600 Subject: [SCSI] ipr: Fixup device type check Fixup a check used by the ipr driver to determine if a given device is a SCSI disk. Due to the addition of support for attaching SATA devices, this check needs to be more robust. Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/ipr.c') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 154b78c5baa..20b6929cb4f 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3214,7 +3214,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) sdev->timeout = IPR_VSET_RW_TIMEOUT; blk_queue_max_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS); } - if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)) + if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res)) sdev->allow_restart = 1; scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); } @@ -4540,7 +4540,7 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) ipr_cmd->job_step = ipr_ioa_reset_done; list_for_each_entry_continue(res, &ioa_cfg->used_res_q, queue) { - if (!IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)) + if (!ipr_is_scsi_disk(res)) continue; ipr_cmd->u.res = res; -- cgit v1.2.3 From fe964d0a4bfa7c25e75c53d81acbf53099777e9e Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 29 Mar 2006 09:37:29 -0600 Subject: [SCSI] ipr: Simplify status area dumping Simplify the dumping of the command status area by removing some device specific information that has proven to not be worthwhile. Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) (limited to 'drivers/scsi/ipr.c') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 20b6929cb4f..dd5c96239e0 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -164,29 +164,6 @@ MODULE_PARM_DESC(auto_create, "Auto-create single device RAID 0 arrays when init MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); -static const char *ipr_gpdd_dev_end_states[] = { - "Command complete", - "Terminated by host", - "Terminated by device reset", - "Terminated by bus reset", - "Unknown", - "Command not started" -}; - -static const char *ipr_gpdd_dev_bus_phases[] = { - "Bus free", - "Arbitration", - "Selection", - "Message out", - "Command", - "Message in", - "Data out", - "Data in", - "Status", - "Reselection", - "Unknown" -}; - /* A constant array of IOASCs/URCs/Error Messages */ static const struct ipr_error_table_t ipr_error_table[] = { @@ -3938,6 +3915,7 @@ static void ipr_erp_cancel_all(struct ipr_cmnd *ipr_cmd) * ipr_dump_ioasa - Dump contents of IOASA * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct + * @res: resource entry struct * * This function is invoked by the interrupt handler when ops * fail. It will log the IOASA if appropriate. Only called @@ -3947,7 +3925,7 @@ static void ipr_erp_cancel_all(struct ipr_cmnd *ipr_cmd) * none **/ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, - struct ipr_cmnd *ipr_cmd) + struct ipr_cmnd *ipr_cmd, struct ipr_resource_entry *res) { int i; u16 data_len; @@ -3975,16 +3953,7 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, return; } - ipr_sdev_err(ipr_cmd->scsi_cmd->device, "%s\n", - ipr_error_table[error_index].error); - - if ((ioasa->u.gpdd.end_state <= ARRAY_SIZE(ipr_gpdd_dev_end_states)) && - (ioasa->u.gpdd.bus_phase <= ARRAY_SIZE(ipr_gpdd_dev_bus_phases))) { - ipr_sdev_err(ipr_cmd->scsi_cmd->device, - "Device End state: %s Phase: %s\n", - ipr_gpdd_dev_end_states[ioasa->u.gpdd.end_state], - ipr_gpdd_dev_bus_phases[ioasa->u.gpdd.bus_phase]); - } + 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 = sizeof(struct ipr_ioasa); @@ -4141,7 +4110,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, } if (ipr_is_gscsi(res)) - ipr_dump_ioasa(ioa_cfg, ipr_cmd); + ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); else ipr_gen_sense(ipr_cmd); -- cgit v1.2.3 From fb3ed3cb4b8ba84e5b0899ef752495f213973843 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 29 Mar 2006 09:37:37 -0600 Subject: [SCSI] ipr: printk macro cleanup/removal Remove some unused printk macros, make some more robust, and convert some to use standard printk macros when possible. Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/scsi/ipr.c') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index dd5c96239e0..69579969913 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -1333,8 +1333,8 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, return; if (ipr_is_device(&hostrcb->hcam.u.error.failing_dev_res_addr)) { - ipr_res_err(ioa_cfg, hostrcb->hcam.u.error.failing_dev_res_addr, - "%s\n", ipr_error_table[error_index].error); + ipr_ra_err(ioa_cfg, hostrcb->hcam.u.error.failing_dev_res_addr, + "%s\n", ipr_error_table[error_index].error); } else { dev_err(&ioa_cfg->pdev->dev, "%s\n", ipr_error_table[error_index].error); @@ -3332,7 +3332,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) cmd_pkt->request_type = IPR_RQTYPE_IOACMD; cmd_pkt->cdb[0] = IPR_RESET_DEVICE; - ipr_sdev_err(scsi_cmd->device, "Resetting device\n"); + scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n"); ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); @@ -3417,7 +3417,7 @@ static void ipr_abort_timeout(struct ipr_cmnd *ipr_cmd) return; } - ipr_sdev_err(ipr_cmd->u.sdev, "Abort timed out. Resetting bus\n"); + sdev_printk(KERN_ERR, ipr_cmd->u.sdev, "Abort timed out. Resetting bus.\n"); reset_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ipr_cmd->sibling = reset_cmd; reset_cmd->sibling = ipr_cmd; @@ -3481,7 +3481,8 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; ipr_cmd->u.sdev = scsi_cmd->device; - ipr_sdev_err(scsi_cmd->device, "Aborting command: %02X\n", scsi_cmd->cmnd[0]); + 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); @@ -3792,8 +3793,8 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { scsi_cmd->result |= (DID_ERROR << 16); - ipr_sdev_err(scsi_cmd->device, - "Request Sense failed with IOASC: 0x%08X\n", ioasc); + scmd_printk(KERN_ERR, scsi_cmd, + "Request Sense failed with IOASC: 0x%08X\n", ioasc); } else { memcpy(scsi_cmd->sense_buffer, ipr_cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); -- cgit v1.2.3 From c65130967186dc53c0c66793cfe640521dcdada2 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 29 Mar 2006 09:37:43 -0600 Subject: [SCSI] ipr: Reset device cleanup Encapsulate some more of the device reset processing in preparation for SATA support. Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 58 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 17 deletions(-) (limited to 'drivers/scsi/ipr.c') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 69579969913..8b80e59c8c5 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3280,6 +3280,44 @@ static int ipr_eh_host_reset(struct scsi_cmnd * cmd) return rc; } +/** + * ipr_device_reset - Reset the device + * @ioa_cfg: ioa config struct + * @res: resource entry struct + * + * This function issues a device reset to the affected device. + * If the device is a SCSI device, a LUN reset will be sent + * to the device first. If that does not work, a target reset + * will be sent. + * + * Return value: + * 0 on success / non-zero on failure + **/ +static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_resource_entry *res) +{ + struct ipr_cmnd *ipr_cmd; + struct ipr_ioarcb *ioarcb; + struct ipr_cmd_pkt *cmd_pkt; + u32 ioasc; + + ENTER; + ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); + ioarcb = &ipr_cmd->ioarcb; + cmd_pkt = &ioarcb->cmd_pkt; + + ioarcb->res_handle = res->cfgte.res_handle; + cmd_pkt->request_type = IPR_RQTYPE_IOACMD; + cmd_pkt->cdb[0] = IPR_RESET_DEVICE; + + ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); + ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); + + LEAVE; + return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0); +} + /** * ipr_eh_dev_reset - Reset the device * @scsi_cmd: scsi command struct @@ -3296,8 +3334,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) struct ipr_cmnd *ipr_cmd; struct ipr_ioa_cfg *ioa_cfg; struct ipr_resource_entry *res; - struct ipr_cmd_pkt *cmd_pkt; - u32 ioasc; + int rc; ENTER; ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; @@ -3324,25 +3361,12 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) } res->resetting_device = 1; - - ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); - - ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; - cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; - cmd_pkt->request_type = IPR_RQTYPE_IOACMD; - cmd_pkt->cdb[0] = IPR_RESET_DEVICE; - scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n"); - ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); - - ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); - + rc = ipr_device_reset(ioa_cfg, res); res->resetting_device = 0; - list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - LEAVE; - return (IPR_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS); + return (rc ? FAILED : SUCCESS); } static int ipr_eh_dev_reset(struct scsi_cmnd * cmd) -- cgit v1.2.3