[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>
This commit is contained in:
@@ -4235,35 +4235,6 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
|
|||||||
ipr_erp_start(ioa_cfg, ipr_cmd);
|
ipr_erp_start(ioa_cfg, ipr_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ipr_save_ioafp_mode_select - Save adapters mode select data
|
|
||||||
* @ioa_cfg: ioa config struct
|
|
||||||
* @scsi_cmd: scsi command struct
|
|
||||||
*
|
|
||||||
* This function saves mode select data for the adapter to
|
|
||||||
* use following an adapter reset.
|
|
||||||
*
|
|
||||||
* Return value:
|
|
||||||
* 0 on success / SCSI_MLQUEUE_HOST_BUSY on failure
|
|
||||||
**/
|
|
||||||
static int ipr_save_ioafp_mode_select(struct ipr_ioa_cfg *ioa_cfg,
|
|
||||||
struct scsi_cmnd *scsi_cmd)
|
|
||||||
{
|
|
||||||
if (!ioa_cfg->saved_mode_pages) {
|
|
||||||
ioa_cfg->saved_mode_pages = kmalloc(sizeof(struct ipr_mode_pages),
|
|
||||||
GFP_ATOMIC);
|
|
||||||
if (!ioa_cfg->saved_mode_pages) {
|
|
||||||
dev_err(&ioa_cfg->pdev->dev,
|
|
||||||
"IOA mode select buffer allocation failed\n");
|
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(ioa_cfg->saved_mode_pages, scsi_cmd->buffer, scsi_cmd->cmnd[4]);
|
|
||||||
ioa_cfg->saved_mode_page_len = scsi_cmd->cmnd[4];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ipr_queuecommand - Queue a mid-layer request
|
* ipr_queuecommand - Queue a mid-layer request
|
||||||
* @scsi_cmd: scsi command struct
|
* @scsi_cmd: scsi command struct
|
||||||
@@ -4338,9 +4309,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
|
|||||||
(!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
|
(!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
|
||||||
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
|
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
|
||||||
|
|
||||||
if (ipr_is_ioa_resource(res) && scsi_cmd->cmnd[0] == MODE_SELECT)
|
|
||||||
rc = ipr_save_ioafp_mode_select(ioa_cfg, scsi_cmd);
|
|
||||||
|
|
||||||
if (likely(rc == 0))
|
if (likely(rc == 0))
|
||||||
rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
|
rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
|
||||||
|
|
||||||
@@ -4829,17 +4797,11 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
|
|||||||
int length;
|
int length;
|
||||||
|
|
||||||
ENTER;
|
ENTER;
|
||||||
if (ioa_cfg->saved_mode_pages) {
|
ipr_scsi_bus_speed_limit(ioa_cfg);
|
||||||
memcpy(mode_pages, ioa_cfg->saved_mode_pages,
|
ipr_check_term_power(ioa_cfg, mode_pages);
|
||||||
ioa_cfg->saved_mode_page_len);
|
ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
|
||||||
length = ioa_cfg->saved_mode_page_len;
|
length = mode_pages->hdr.length + 1;
|
||||||
} else {
|
mode_pages->hdr.length = 0;
|
||||||
ipr_scsi_bus_speed_limit(ioa_cfg);
|
|
||||||
ipr_check_term_power(ioa_cfg, mode_pages);
|
|
||||||
ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
|
|
||||||
length = mode_pages->hdr.length + 1;
|
|
||||||
mode_pages->hdr.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11,
|
ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11,
|
||||||
ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
|
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ipr_free_dump(ioa_cfg);
|
ipr_free_dump(ioa_cfg);
|
||||||
kfree(ioa_cfg->saved_mode_pages);
|
|
||||||
kfree(ioa_cfg->trace);
|
kfree(ioa_cfg->trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,8 +36,8 @@
|
|||||||
/*
|
/*
|
||||||
* Literals
|
* Literals
|
||||||
*/
|
*/
|
||||||
#define IPR_DRIVER_VERSION "2.1.1"
|
#define IPR_DRIVER_VERSION "2.1.2"
|
||||||
#define IPR_DRIVER_DATE "(November 15, 2005)"
|
#define IPR_DRIVER_DATE "(February 8, 2006)"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
|
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
|
||||||
@@ -1000,7 +1000,6 @@ struct ipr_ioa_cfg {
|
|||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
struct ipr_sglist *ucode_sglist;
|
struct ipr_sglist *ucode_sglist;
|
||||||
struct ipr_mode_pages *saved_mode_pages;
|
|
||||||
u8 saved_mode_page_len;
|
u8 saved_mode_page_len;
|
||||||
|
|
||||||
struct work_struct work_q;
|
struct work_struct work_q;
|
||||||
|
Reference in New Issue
Block a user