Loading drivers/scsi/ipr.c +135 −5 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ static unsigned int ipr_fastfail = 0; static unsigned int ipr_transop_timeout = 0; static unsigned int ipr_enable_cache = 1; static unsigned int ipr_debug = 0; static unsigned int ipr_dual_ioa_raid = 1; static DEFINE_SPINLOCK(ipr_driver_lock); /* This table describes the differences between DMA controller chips */ Loading Loading @@ -158,6 +159,8 @@ module_param_named(enable_cache, ipr_enable_cache, int, 0); MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); module_param_named(debug, ipr_debug, int, 0); MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); Loading Loading @@ -5881,6 +5884,94 @@ static int ipr_ioafp_mode_sense_page28(struct ipr_cmnd *ipr_cmd) return IPR_RC_JOB_RETURN; } /** * ipr_ioafp_mode_select_page24 - Issue Mode Select to IOA * @ipr_cmd: ipr command struct * * This function enables dual IOA RAID support if possible. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_select_page24(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_mode_pages *mode_pages = &ioa_cfg->vpd_cbs->mode_pages; struct ipr_mode_page24 *mode_page; int length; ENTER; mode_page = ipr_get_mode_page(mode_pages, 0x24, sizeof(struct ipr_mode_page24)); if (mode_page) mode_page->flags |= IPR_ENABLE_DUAL_IOA_AF; 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, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), length); ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); LEAVE; return IPR_RC_JOB_RETURN; } /** * ipr_reset_mode_sense_page24_failed - Handle failure of IOAFP mode sense * @ipr_cmd: ipr command struct * * This function handles the failure of a Mode Sense to the IOAFP. * Some adapters do not handle all mode pages. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd) { u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; return IPR_RC_JOB_CONTINUE; } return ipr_reset_cmd_failed(ipr_cmd); } /** * ipr_ioafp_mode_sense_page24 - Issue Page 24 Mode Sense to IOA * @ipr_cmd: ipr command struct * * This function send a mode sense to the IOA to retrieve * the IOA Advanced Function Control mode page. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_sense_page24(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; ENTER; ipr_build_mode_sense(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x24, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), sizeof(struct ipr_mode_pages)); ipr_cmd->job_step = ipr_ioafp_mode_select_page24; ipr_cmd->job_step_failed = ipr_reset_mode_sense_page24_failed; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); LEAVE; return IPR_RC_JOB_RETURN; } /** * ipr_init_res_table - Initialize the resource table * @ipr_cmd: ipr command struct Loading Loading @@ -5949,6 +6040,9 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) } } if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; else ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; LEAVE; Loading @@ -5971,8 +6065,11 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; ENTER; if (cap->cap & IPR_CAP_DUAL_IOA_RAID) ioa_cfg->dual_raid = 1; dev_info(&ioa_cfg->pdev->dev, "Adapter firmware version: %02X%02X%02X%02X\n", ucode_vpd->major_release, ucode_vpd->card_type, ucode_vpd->minor_release[0], ucode_vpd->minor_release[1]); Loading Loading @@ -6055,6 +6152,37 @@ static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page) return 0; } /** * ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter. * @ipr_cmd: ipr command struct * * This function sends a Page 0xD0 inquiry to the adapter * to retrieve adapter capabilities. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data; struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; ENTER; ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; memset(cap, 0, sizeof(*cap)); if (ipr_inquiry_page_supported(page0, 0xD0)) { ipr_ioafp_inquiry(ipr_cmd, 1, 0xD0, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, cap), sizeof(struct ipr_inquiry_cap)); return IPR_RC_JOB_RETURN; } LEAVE; return IPR_RC_JOB_CONTINUE; } /** * ipr_ioafp_page3_inquiry - Send a Page 3 Inquiry to the adapter. * @ipr_cmd: ipr command struct Loading @@ -6075,7 +6203,7 @@ static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) if (!ipr_inquiry_page_supported(page0, 1)) ioa_cfg->cache_state = CACHE_NONE; ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; ipr_cmd->job_step = ipr_ioafp_cap_inquiry; ipr_ioafp_inquiry(ipr_cmd, 1, 3, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page3_data), Loading Loading @@ -6679,12 +6807,14 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd) ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; ipr_cmd->ioarcb.cmd_pkt.cdb[1] = shutdown_type; if (shutdown_type == IPR_SHUTDOWN_ABBREV) timeout = IPR_ABBREV_SHUTDOWN_TIMEOUT; if (shutdown_type == IPR_SHUTDOWN_NORMAL) timeout = IPR_SHUTDOWN_TIMEOUT; else if (shutdown_type == IPR_SHUTDOWN_PREPARE_FOR_NORMAL) timeout = IPR_INTERNAL_TIMEOUT; else if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) timeout = IPR_DUAL_IOA_ABBR_SHUTDOWN_TO; else timeout = IPR_SHUTDOWN_TIMEOUT; timeout = IPR_ABBREV_SHUTDOWN_TIMEOUT; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, timeout); Loading drivers/scsi/ipr.h +24 −2 Original line number Diff line number Diff line Loading @@ -37,8 +37,8 @@ /* * Literals */ #define IPR_DRIVER_VERSION "2.3.2" #define IPR_DRIVER_DATE "(March 23, 2007)" #define IPR_DRIVER_VERSION "2.4.0" #define IPR_DRIVER_DATE "(April 24, 2007)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding Loading Loading @@ -180,6 +180,7 @@ #define IPR_SHUTDOWN_TIMEOUT (ipr_fastfail ? 60 * HZ : 10 * 60 * HZ) #define IPR_VSET_RW_TIMEOUT (ipr_fastfail ? 30 * HZ : 2 * 60 * HZ) #define IPR_ABBREV_SHUTDOWN_TIMEOUT (10 * HZ) #define IPR_DUAL_IOA_ABBR_SHUTDOWN_TO (2 * 60 * HZ) #define IPR_DEVICE_RESET_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) #define IPR_CANCEL_ALL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) #define IPR_ABORT_TASK_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) Loading Loading @@ -603,6 +604,12 @@ struct ipr_mode_page28 { struct ipr_dev_bus_entry bus[0]; }__attribute__((packed)); struct ipr_mode_page24 { struct ipr_mode_page_hdr hdr; u8 flags; #define IPR_ENABLE_DUAL_IOA_AF 0x80 }__attribute__((packed)); struct ipr_ioa_vpd { struct ipr_std_inq_data std_inq_data; u8 ascii_part_num[12]; Loading @@ -625,6 +632,19 @@ struct ipr_inquiry_page3 { u8 patch_number[4]; }__attribute__((packed)); struct ipr_inquiry_cap { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 ascii_len; u8 reserved2; u8 sis_version[2]; u8 cap; #define IPR_CAP_DUAL_IOA_RAID 0x80 u8 reserved3[15]; }__attribute__((packed)); #define IPR_INQUIRY_PAGE0_ENTRIES 20 struct ipr_inquiry_page0 { u8 peri_qual_dev_type; Loading Loading @@ -963,6 +983,7 @@ struct ipr_misc_cbs { struct ipr_ioa_vpd ioa_vpd; struct ipr_inquiry_page0 page0_data; struct ipr_inquiry_page3 page3_data; struct ipr_inquiry_cap cap; struct ipr_mode_pages mode_pages; struct ipr_supported_device supp_dev; }; Loading Loading @@ -1069,6 +1090,7 @@ struct ipr_ioa_cfg { u8 allow_cmds:1; u8 allow_ml_add_del:1; u8 needs_hard_reset:1; u8 dual_raid:1; enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ Loading Loading
drivers/scsi/ipr.c +135 −5 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ static unsigned int ipr_fastfail = 0; static unsigned int ipr_transop_timeout = 0; static unsigned int ipr_enable_cache = 1; static unsigned int ipr_debug = 0; static unsigned int ipr_dual_ioa_raid = 1; static DEFINE_SPINLOCK(ipr_driver_lock); /* This table describes the differences between DMA controller chips */ Loading Loading @@ -158,6 +159,8 @@ module_param_named(enable_cache, ipr_enable_cache, int, 0); MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); module_param_named(debug, ipr_debug, int, 0); MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); Loading Loading @@ -5881,6 +5884,94 @@ static int ipr_ioafp_mode_sense_page28(struct ipr_cmnd *ipr_cmd) return IPR_RC_JOB_RETURN; } /** * ipr_ioafp_mode_select_page24 - Issue Mode Select to IOA * @ipr_cmd: ipr command struct * * This function enables dual IOA RAID support if possible. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_select_page24(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_mode_pages *mode_pages = &ioa_cfg->vpd_cbs->mode_pages; struct ipr_mode_page24 *mode_page; int length; ENTER; mode_page = ipr_get_mode_page(mode_pages, 0x24, sizeof(struct ipr_mode_page24)); if (mode_page) mode_page->flags |= IPR_ENABLE_DUAL_IOA_AF; 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, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), length); ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); LEAVE; return IPR_RC_JOB_RETURN; } /** * ipr_reset_mode_sense_page24_failed - Handle failure of IOAFP mode sense * @ipr_cmd: ipr command struct * * This function handles the failure of a Mode Sense to the IOAFP. * Some adapters do not handle all mode pages. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd) { u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; return IPR_RC_JOB_CONTINUE; } return ipr_reset_cmd_failed(ipr_cmd); } /** * ipr_ioafp_mode_sense_page24 - Issue Page 24 Mode Sense to IOA * @ipr_cmd: ipr command struct * * This function send a mode sense to the IOA to retrieve * the IOA Advanced Function Control mode page. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_sense_page24(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; ENTER; ipr_build_mode_sense(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x24, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), sizeof(struct ipr_mode_pages)); ipr_cmd->job_step = ipr_ioafp_mode_select_page24; ipr_cmd->job_step_failed = ipr_reset_mode_sense_page24_failed; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); LEAVE; return IPR_RC_JOB_RETURN; } /** * ipr_init_res_table - Initialize the resource table * @ipr_cmd: ipr command struct Loading Loading @@ -5949,6 +6040,9 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) } } if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; else ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; LEAVE; Loading @@ -5971,8 +6065,11 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; ENTER; if (cap->cap & IPR_CAP_DUAL_IOA_RAID) ioa_cfg->dual_raid = 1; dev_info(&ioa_cfg->pdev->dev, "Adapter firmware version: %02X%02X%02X%02X\n", ucode_vpd->major_release, ucode_vpd->card_type, ucode_vpd->minor_release[0], ucode_vpd->minor_release[1]); Loading Loading @@ -6055,6 +6152,37 @@ static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page) return 0; } /** * ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter. * @ipr_cmd: ipr command struct * * This function sends a Page 0xD0 inquiry to the adapter * to retrieve adapter capabilities. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data; struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; ENTER; ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; memset(cap, 0, sizeof(*cap)); if (ipr_inquiry_page_supported(page0, 0xD0)) { ipr_ioafp_inquiry(ipr_cmd, 1, 0xD0, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, cap), sizeof(struct ipr_inquiry_cap)); return IPR_RC_JOB_RETURN; } LEAVE; return IPR_RC_JOB_CONTINUE; } /** * ipr_ioafp_page3_inquiry - Send a Page 3 Inquiry to the adapter. * @ipr_cmd: ipr command struct Loading @@ -6075,7 +6203,7 @@ static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) if (!ipr_inquiry_page_supported(page0, 1)) ioa_cfg->cache_state = CACHE_NONE; ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; ipr_cmd->job_step = ipr_ioafp_cap_inquiry; ipr_ioafp_inquiry(ipr_cmd, 1, 3, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page3_data), Loading Loading @@ -6679,12 +6807,14 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd) ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; ipr_cmd->ioarcb.cmd_pkt.cdb[1] = shutdown_type; if (shutdown_type == IPR_SHUTDOWN_ABBREV) timeout = IPR_ABBREV_SHUTDOWN_TIMEOUT; if (shutdown_type == IPR_SHUTDOWN_NORMAL) timeout = IPR_SHUTDOWN_TIMEOUT; else if (shutdown_type == IPR_SHUTDOWN_PREPARE_FOR_NORMAL) timeout = IPR_INTERNAL_TIMEOUT; else if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) timeout = IPR_DUAL_IOA_ABBR_SHUTDOWN_TO; else timeout = IPR_SHUTDOWN_TIMEOUT; timeout = IPR_ABBREV_SHUTDOWN_TIMEOUT; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, timeout); Loading
drivers/scsi/ipr.h +24 −2 Original line number Diff line number Diff line Loading @@ -37,8 +37,8 @@ /* * Literals */ #define IPR_DRIVER_VERSION "2.3.2" #define IPR_DRIVER_DATE "(March 23, 2007)" #define IPR_DRIVER_VERSION "2.4.0" #define IPR_DRIVER_DATE "(April 24, 2007)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding Loading Loading @@ -180,6 +180,7 @@ #define IPR_SHUTDOWN_TIMEOUT (ipr_fastfail ? 60 * HZ : 10 * 60 * HZ) #define IPR_VSET_RW_TIMEOUT (ipr_fastfail ? 30 * HZ : 2 * 60 * HZ) #define IPR_ABBREV_SHUTDOWN_TIMEOUT (10 * HZ) #define IPR_DUAL_IOA_ABBR_SHUTDOWN_TO (2 * 60 * HZ) #define IPR_DEVICE_RESET_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) #define IPR_CANCEL_ALL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) #define IPR_ABORT_TASK_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) Loading Loading @@ -603,6 +604,12 @@ struct ipr_mode_page28 { struct ipr_dev_bus_entry bus[0]; }__attribute__((packed)); struct ipr_mode_page24 { struct ipr_mode_page_hdr hdr; u8 flags; #define IPR_ENABLE_DUAL_IOA_AF 0x80 }__attribute__((packed)); struct ipr_ioa_vpd { struct ipr_std_inq_data std_inq_data; u8 ascii_part_num[12]; Loading @@ -625,6 +632,19 @@ struct ipr_inquiry_page3 { u8 patch_number[4]; }__attribute__((packed)); struct ipr_inquiry_cap { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 ascii_len; u8 reserved2; u8 sis_version[2]; u8 cap; #define IPR_CAP_DUAL_IOA_RAID 0x80 u8 reserved3[15]; }__attribute__((packed)); #define IPR_INQUIRY_PAGE0_ENTRIES 20 struct ipr_inquiry_page0 { u8 peri_qual_dev_type; Loading Loading @@ -963,6 +983,7 @@ struct ipr_misc_cbs { struct ipr_ioa_vpd ioa_vpd; struct ipr_inquiry_page0 page0_data; struct ipr_inquiry_page3 page3_data; struct ipr_inquiry_cap cap; struct ipr_mode_pages mode_pages; struct ipr_supported_device supp_dev; }; Loading Loading @@ -1069,6 +1090,7 @@ struct ipr_ioa_cfg { u8 allow_cmds:1; u8 allow_ml_add_del:1; u8 needs_hard_reset:1; u8 dual_raid:1; enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ Loading