aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBrian King <brking@us.ibm.com>2006-02-08 21:57:42 -0500
committer <jejb@mulgrave.il.steeleye.com>2006-02-12 12:05:44 -0500
commit4733804c9f62fbc17ba69e8654a5fdf465f5bc41 (patch)
tree4ed2f54a67b5529d7b017c8044264041d0bdaa81 /drivers
parent0d4be1240b2668b6a3ffadb15eb660baf52f8377 (diff)
[SCSI] ipr: Fix adapter initialization failure
Since scsi core is always sending scatterlists now, remove some code which was written with the bad assumption that a small transfer would not be sent down in a scatterlist. Without this fix, the ipr driver ends up sending garbage data to the adapter following a reset, causing it to fail the reset and take the adapter offline. Signed-off-by: Brian King <brking@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/ipr.c49
-rw-r--r--drivers/scsi/ipr.h5
2 files changed, 7 insertions, 47 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 27acf78cf8d8..2bba5e55d7bc 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4236,35 +4236,6 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
4236} 4236}
4237 4237
4238/** 4238/**
4239 * ipr_save_ioafp_mode_select - Save adapters mode select data
4240 * @ioa_cfg: ioa config struct
4241 * @scsi_cmd: scsi command struct
4242 *
4243 * This function saves mode select data for the adapter to
4244 * use following an adapter reset.
4245 *
4246 * Return value:
4247 * 0 on success / SCSI_MLQUEUE_HOST_BUSY on failure
4248 **/
4249static int ipr_save_ioafp_mode_select(struct ipr_ioa_cfg *ioa_cfg,
4250 struct scsi_cmnd *scsi_cmd)
4251{
4252 if (!ioa_cfg->saved_mode_pages) {
4253 ioa_cfg->saved_mode_pages = kmalloc(sizeof(struct ipr_mode_pages),
4254 GFP_ATOMIC);
4255 if (!ioa_cfg->saved_mode_pages) {
4256 dev_err(&ioa_cfg->pdev->dev,
4257 "IOA mode select buffer allocation failed\n");
4258 return SCSI_MLQUEUE_HOST_BUSY;
4259 }
4260 }
4261
4262 memcpy(ioa_cfg->saved_mode_pages, scsi_cmd->buffer, scsi_cmd->cmnd[4]);
4263 ioa_cfg->saved_mode_page_len = scsi_cmd->cmnd[4];
4264 return 0;
4265}
4266
4267/**
4268 * ipr_queuecommand - Queue a mid-layer request 4239 * ipr_queuecommand - Queue a mid-layer request
4269 * @scsi_cmd: scsi command struct 4240 * @scsi_cmd: scsi command struct
4270 * @done: done function 4241 * @done: done function
@@ -4338,9 +4309,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
4338 (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) 4309 (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
4339 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; 4310 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
4340 4311
4341 if (ipr_is_ioa_resource(res) && scsi_cmd->cmnd[0] == MODE_SELECT)
4342 rc = ipr_save_ioafp_mode_select(ioa_cfg, scsi_cmd);
4343
4344 if (likely(rc == 0)) 4312 if (likely(rc == 0))
4345 rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); 4313 rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
4346 4314
@@ -4829,17 +4797,11 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
4829 int length; 4797 int length;
4830 4798
4831 ENTER; 4799 ENTER;
4832 if (ioa_cfg->saved_mode_pages) { 4800 ipr_scsi_bus_speed_limit(ioa_cfg);
4833 memcpy(mode_pages, ioa_cfg->saved_mode_pages, 4801 ipr_check_term_power(ioa_cfg, mode_pages);
4834 ioa_cfg->saved_mode_page_len); 4802 ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
4835 length = ioa_cfg->saved_mode_page_len; 4803 length = mode_pages->hdr.length + 1;
4836 } else { 4804 mode_pages->hdr.length = 0;
4837 ipr_scsi_bus_speed_limit(ioa_cfg);
4838 ipr_check_term_power(ioa_cfg, mode_pages);
4839 ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
4840 length = mode_pages->hdr.length + 1;
4841 mode_pages->hdr.length = 0;
4842 }
4843 4805
4844 ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11, 4806 ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11,
4845 ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), 4807 ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
@@ -5969,7 +5931,6 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
5969 } 5931 }
5970 5932
5971 ipr_free_dump(ioa_cfg); 5933 ipr_free_dump(ioa_cfg);
5972 kfree(ioa_cfg->saved_mode_pages);
5973 kfree(ioa_cfg->trace); 5934 kfree(ioa_cfg->trace);
5974} 5935}
5975 5936
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index b639332131f1..fd360bfe56dd 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -36,8 +36,8 @@
36/* 36/*
37 * Literals 37 * Literals
38 */ 38 */
39#define IPR_DRIVER_VERSION "2.1.1" 39#define IPR_DRIVER_VERSION "2.1.2"
40#define IPR_DRIVER_DATE "(November 15, 2005)" 40#define IPR_DRIVER_DATE "(February 8, 2006)"
41 41
42/* 42/*
43 * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding 43 * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -1000,7 +1000,6 @@ struct ipr_ioa_cfg {
1000 struct Scsi_Host *host; 1000 struct Scsi_Host *host;
1001 struct pci_dev *pdev; 1001 struct pci_dev *pdev;
1002 struct ipr_sglist *ucode_sglist; 1002 struct ipr_sglist *ucode_sglist;
1003 struct ipr_mode_pages *saved_mode_pages;
1004 u8 saved_mode_page_len; 1003 u8 saved_mode_page_len;
1005 1004
1006 struct work_struct work_q; 1005 struct work_struct work_q;