diff options
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r-- | drivers/scsi/ipr.c | 1756 |
1 files changed, 1346 insertions, 410 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 032f0d0e6cb4..c79cd98eb6bf 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -72,6 +72,8 @@ | |||
72 | #include <linux/moduleparam.h> | 72 | #include <linux/moduleparam.h> |
73 | #include <linux/libata.h> | 73 | #include <linux/libata.h> |
74 | #include <linux/hdreg.h> | 74 | #include <linux/hdreg.h> |
75 | #include <linux/reboot.h> | ||
76 | #include <linux/stringify.h> | ||
75 | #include <asm/io.h> | 77 | #include <asm/io.h> |
76 | #include <asm/irq.h> | 78 | #include <asm/irq.h> |
77 | #include <asm/processor.h> | 79 | #include <asm/processor.h> |
@@ -91,8 +93,8 @@ static unsigned int ipr_max_speed = 1; | |||
91 | static int ipr_testmode = 0; | 93 | static int ipr_testmode = 0; |
92 | static unsigned int ipr_fastfail = 0; | 94 | static unsigned int ipr_fastfail = 0; |
93 | static unsigned int ipr_transop_timeout = 0; | 95 | static unsigned int ipr_transop_timeout = 0; |
94 | static unsigned int ipr_enable_cache = 1; | ||
95 | static unsigned int ipr_debug = 0; | 96 | static unsigned int ipr_debug = 0; |
97 | static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS; | ||
96 | static unsigned int ipr_dual_ioa_raid = 1; | 98 | static unsigned int ipr_dual_ioa_raid = 1; |
97 | static DEFINE_SPINLOCK(ipr_driver_lock); | 99 | static DEFINE_SPINLOCK(ipr_driver_lock); |
98 | 100 | ||
@@ -104,13 +106,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | |||
104 | { | 106 | { |
105 | .set_interrupt_mask_reg = 0x0022C, | 107 | .set_interrupt_mask_reg = 0x0022C, |
106 | .clr_interrupt_mask_reg = 0x00230, | 108 | .clr_interrupt_mask_reg = 0x00230, |
109 | .clr_interrupt_mask_reg32 = 0x00230, | ||
107 | .sense_interrupt_mask_reg = 0x0022C, | 110 | .sense_interrupt_mask_reg = 0x0022C, |
111 | .sense_interrupt_mask_reg32 = 0x0022C, | ||
108 | .clr_interrupt_reg = 0x00228, | 112 | .clr_interrupt_reg = 0x00228, |
113 | .clr_interrupt_reg32 = 0x00228, | ||
109 | .sense_interrupt_reg = 0x00224, | 114 | .sense_interrupt_reg = 0x00224, |
115 | .sense_interrupt_reg32 = 0x00224, | ||
110 | .ioarrin_reg = 0x00404, | 116 | .ioarrin_reg = 0x00404, |
111 | .sense_uproc_interrupt_reg = 0x00214, | 117 | .sense_uproc_interrupt_reg = 0x00214, |
118 | .sense_uproc_interrupt_reg32 = 0x00214, | ||
112 | .set_uproc_interrupt_reg = 0x00214, | 119 | .set_uproc_interrupt_reg = 0x00214, |
113 | .clr_uproc_interrupt_reg = 0x00218 | 120 | .set_uproc_interrupt_reg32 = 0x00214, |
121 | .clr_uproc_interrupt_reg = 0x00218, | ||
122 | .clr_uproc_interrupt_reg32 = 0x00218 | ||
114 | } | 123 | } |
115 | }, | 124 | }, |
116 | { /* Snipe and Scamp */ | 125 | { /* Snipe and Scamp */ |
@@ -119,25 +128,59 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | |||
119 | { | 128 | { |
120 | .set_interrupt_mask_reg = 0x00288, | 129 | .set_interrupt_mask_reg = 0x00288, |
121 | .clr_interrupt_mask_reg = 0x0028C, | 130 | .clr_interrupt_mask_reg = 0x0028C, |
131 | .clr_interrupt_mask_reg32 = 0x0028C, | ||
122 | .sense_interrupt_mask_reg = 0x00288, | 132 | .sense_interrupt_mask_reg = 0x00288, |
133 | .sense_interrupt_mask_reg32 = 0x00288, | ||
123 | .clr_interrupt_reg = 0x00284, | 134 | .clr_interrupt_reg = 0x00284, |
135 | .clr_interrupt_reg32 = 0x00284, | ||
124 | .sense_interrupt_reg = 0x00280, | 136 | .sense_interrupt_reg = 0x00280, |
137 | .sense_interrupt_reg32 = 0x00280, | ||
125 | .ioarrin_reg = 0x00504, | 138 | .ioarrin_reg = 0x00504, |
126 | .sense_uproc_interrupt_reg = 0x00290, | 139 | .sense_uproc_interrupt_reg = 0x00290, |
140 | .sense_uproc_interrupt_reg32 = 0x00290, | ||
127 | .set_uproc_interrupt_reg = 0x00290, | 141 | .set_uproc_interrupt_reg = 0x00290, |
128 | .clr_uproc_interrupt_reg = 0x00294 | 142 | .set_uproc_interrupt_reg32 = 0x00290, |
143 | .clr_uproc_interrupt_reg = 0x00294, | ||
144 | .clr_uproc_interrupt_reg32 = 0x00294 | ||
145 | } | ||
146 | }, | ||
147 | { /* CRoC */ | ||
148 | .mailbox = 0x00040, | ||
149 | .cache_line_size = 0x20, | ||
150 | { | ||
151 | .set_interrupt_mask_reg = 0x00010, | ||
152 | .clr_interrupt_mask_reg = 0x00018, | ||
153 | .clr_interrupt_mask_reg32 = 0x0001C, | ||
154 | .sense_interrupt_mask_reg = 0x00010, | ||
155 | .sense_interrupt_mask_reg32 = 0x00014, | ||
156 | .clr_interrupt_reg = 0x00008, | ||
157 | .clr_interrupt_reg32 = 0x0000C, | ||
158 | .sense_interrupt_reg = 0x00000, | ||
159 | .sense_interrupt_reg32 = 0x00004, | ||
160 | .ioarrin_reg = 0x00070, | ||
161 | .sense_uproc_interrupt_reg = 0x00020, | ||
162 | .sense_uproc_interrupt_reg32 = 0x00024, | ||
163 | .set_uproc_interrupt_reg = 0x00020, | ||
164 | .set_uproc_interrupt_reg32 = 0x00024, | ||
165 | .clr_uproc_interrupt_reg = 0x00028, | ||
166 | .clr_uproc_interrupt_reg32 = 0x0002C, | ||
167 | .init_feedback_reg = 0x0005C, | ||
168 | .dump_addr_reg = 0x00064, | ||
169 | .dump_data_reg = 0x00068 | ||
129 | } | 170 | } |
130 | }, | 171 | }, |
131 | }; | 172 | }; |
132 | 173 | ||
133 | static const struct ipr_chip_t ipr_chip[] = { | 174 | static const struct ipr_chip_t ipr_chip[] = { |
134 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 175 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
135 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 176 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
136 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 177 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
137 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 178 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
138 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] }, | 179 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
139 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] }, | 180 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] }, |
140 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] } | 181 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] }, |
182 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] }, | ||
183 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] } | ||
141 | }; | 184 | }; |
142 | 185 | ||
143 | static int ipr_max_bus_speeds [] = { | 186 | static int ipr_max_bus_speeds [] = { |
@@ -156,12 +199,13 @@ module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR); | |||
156 | MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); | 199 | MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); |
157 | module_param_named(transop_timeout, ipr_transop_timeout, int, 0); | 200 | module_param_named(transop_timeout, ipr_transop_timeout, int, 0); |
158 | MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); | 201 | MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); |
159 | module_param_named(enable_cache, ipr_enable_cache, int, 0); | ||
160 | MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); | ||
161 | module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); | 202 | module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); |
162 | MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); | 203 | MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); |
163 | module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); | 204 | module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); |
164 | MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); | 205 | MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); |
206 | module_param_named(max_devs, ipr_max_devs, int, 0); | ||
207 | MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. " | ||
208 | "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]"); | ||
165 | MODULE_LICENSE("GPL"); | 209 | MODULE_LICENSE("GPL"); |
166 | MODULE_VERSION(IPR_DRIVER_VERSION); | 210 | MODULE_VERSION(IPR_DRIVER_VERSION); |
167 | 211 | ||
@@ -180,6 +224,20 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
180 | "FFFE: Soft device bus error recovered by the IOA"}, | 224 | "FFFE: Soft device bus error recovered by the IOA"}, |
181 | {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, | 225 | {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, |
182 | "4101: Soft device bus fabric error"}, | 226 | "4101: Soft device bus fabric error"}, |
227 | {0x01100100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
228 | "FFFC: Logical block guard error recovered by the device"}, | ||
229 | {0x01100300, 0, IPR_DEFAULT_LOG_LEVEL, | ||
230 | "FFFC: Logical block reference tag error recovered by the device"}, | ||
231 | {0x01108300, 0, IPR_DEFAULT_LOG_LEVEL, | ||
232 | "4171: Recovered scatter list tag / sequence number error"}, | ||
233 | {0x01109000, 0, IPR_DEFAULT_LOG_LEVEL, | ||
234 | "FF3D: Recovered logical block CRC error on IOA to Host transfer"}, | ||
235 | {0x01109200, 0, IPR_DEFAULT_LOG_LEVEL, | ||
236 | "4171: Recovered logical block sequence number error on IOA to Host transfer"}, | ||
237 | {0x0110A000, 0, IPR_DEFAULT_LOG_LEVEL, | ||
238 | "FFFD: Recovered logical block reference tag error detected by the IOA"}, | ||
239 | {0x0110A100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
240 | "FFFD: Logical block guard error recovered by the IOA"}, | ||
183 | {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, | 241 | {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, |
184 | "FFF9: Device sector reassign successful"}, | 242 | "FFF9: Device sector reassign successful"}, |
185 | {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, | 243 | {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, |
@@ -236,12 +294,28 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
236 | "3120: SCSI bus is not operational"}, | 294 | "3120: SCSI bus is not operational"}, |
237 | {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, | 295 | {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, |
238 | "4100: Hard device bus fabric error"}, | 296 | "4100: Hard device bus fabric error"}, |
297 | {0x04100100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
298 | "310C: Logical block guard error detected by the device"}, | ||
299 | {0x04100300, 0, IPR_DEFAULT_LOG_LEVEL, | ||
300 | "310C: Logical block reference tag error detected by the device"}, | ||
301 | {0x04108300, 1, IPR_DEFAULT_LOG_LEVEL, | ||
302 | "4170: Scatter list tag / sequence number error"}, | ||
303 | {0x04109000, 1, IPR_DEFAULT_LOG_LEVEL, | ||
304 | "8150: Logical block CRC error on IOA to Host transfer"}, | ||
305 | {0x04109200, 1, IPR_DEFAULT_LOG_LEVEL, | ||
306 | "4170: Logical block sequence number error on IOA to Host transfer"}, | ||
307 | {0x0410A000, 0, IPR_DEFAULT_LOG_LEVEL, | ||
308 | "310D: Logical block reference tag error detected by the IOA"}, | ||
309 | {0x0410A100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
310 | "310D: Logical block guard error detected by the IOA"}, | ||
239 | {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, | 311 | {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, |
240 | "9000: IOA reserved area data check"}, | 312 | "9000: IOA reserved area data check"}, |
241 | {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, | 313 | {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, |
242 | "9001: IOA reserved area invalid data pattern"}, | 314 | "9001: IOA reserved area invalid data pattern"}, |
243 | {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, | 315 | {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, |
244 | "9002: IOA reserved area LRC error"}, | 316 | "9002: IOA reserved area LRC error"}, |
317 | {0x04118300, 1, IPR_DEFAULT_LOG_LEVEL, | ||
318 | "Hardware Error, IOA metadata access error"}, | ||
245 | {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, | 319 | {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, |
246 | "102E: Out of alternate sectors for disk storage"}, | 320 | "102E: Out of alternate sectors for disk storage"}, |
247 | {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, | 321 | {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, |
@@ -306,6 +380,8 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
306 | "Illegal request, commands not allowed to this device"}, | 380 | "Illegal request, commands not allowed to this device"}, |
307 | {0x05258100, 0, 0, | 381 | {0x05258100, 0, 0, |
308 | "Illegal request, command not allowed to a secondary adapter"}, | 382 | "Illegal request, command not allowed to a secondary adapter"}, |
383 | {0x05258200, 0, 0, | ||
384 | "Illegal request, command not allowed to a non-optimized resource"}, | ||
309 | {0x05260000, 0, 0, | 385 | {0x05260000, 0, 0, |
310 | "Illegal request, invalid field in parameter list"}, | 386 | "Illegal request, invalid field in parameter list"}, |
311 | {0x05260100, 0, 0, | 387 | {0x05260100, 0, 0, |
@@ -468,7 +544,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, | |||
468 | trace_entry->time = jiffies; | 544 | trace_entry->time = jiffies; |
469 | trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; | 545 | trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; |
470 | trace_entry->type = type; | 546 | trace_entry->type = type; |
471 | trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command; | 547 | if (ipr_cmd->ioa_cfg->sis64) |
548 | trace_entry->ata_op_code = ipr_cmd->i.ata_ioadl.regs.command; | ||
549 | else | ||
550 | trace_entry->ata_op_code = ipr_cmd->ioarcb.u.add_data.u.regs.command; | ||
472 | trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff; | 551 | trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff; |
473 | trace_entry->res_handle = ipr_cmd->ioarcb.res_handle; | 552 | trace_entry->res_handle = ipr_cmd->ioarcb.res_handle; |
474 | trace_entry->u.add_data = add_data; | 553 | trace_entry->u.add_data = add_data; |
@@ -488,16 +567,23 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) | |||
488 | { | 567 | { |
489 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 568 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
490 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 569 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; |
491 | dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); | 570 | dma_addr_t dma_addr = ipr_cmd->dma_addr; |
492 | 571 | ||
493 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); | 572 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); |
494 | ioarcb->write_data_transfer_length = 0; | 573 | ioarcb->data_transfer_length = 0; |
495 | ioarcb->read_data_transfer_length = 0; | 574 | ioarcb->read_data_transfer_length = 0; |
496 | ioarcb->write_ioadl_len = 0; | 575 | ioarcb->ioadl_len = 0; |
497 | ioarcb->read_ioadl_len = 0; | 576 | ioarcb->read_ioadl_len = 0; |
498 | ioarcb->write_ioadl_addr = | 577 | |
499 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); | 578 | if (ipr_cmd->ioa_cfg->sis64) |
500 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 579 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
580 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); | ||
581 | else { | ||
582 | ioarcb->write_ioadl_addr = | ||
583 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | ||
584 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | ||
585 | } | ||
586 | |||
501 | ioasa->ioasc = 0; | 587 | ioasa->ioasc = 0; |
502 | ioasa->residual_data_len = 0; | 588 | ioasa->residual_data_len = 0; |
503 | ioasa->u.gata.status = 0; | 589 | ioasa->u.gata.status = 0; |
@@ -562,10 +648,15 @@ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg, | |||
562 | ioa_cfg->allow_interrupts = 0; | 648 | ioa_cfg->allow_interrupts = 0; |
563 | 649 | ||
564 | /* Set interrupt mask to stop all new interrupts */ | 650 | /* Set interrupt mask to stop all new interrupts */ |
565 | writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); | 651 | if (ioa_cfg->sis64) |
652 | writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg); | ||
653 | else | ||
654 | writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); | ||
566 | 655 | ||
567 | /* Clear any pending interrupts */ | 656 | /* Clear any pending interrupts */ |
568 | writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg); | 657 | if (ioa_cfg->sis64) |
658 | writel(~0, ioa_cfg->regs.clr_interrupt_reg); | ||
659 | writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32); | ||
569 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); | 660 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); |
570 | } | 661 | } |
571 | 662 | ||
@@ -693,6 +784,35 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) | |||
693 | } | 784 | } |
694 | 785 | ||
695 | /** | 786 | /** |
787 | * ipr_send_command - Send driver initiated requests. | ||
788 | * @ipr_cmd: ipr command struct | ||
789 | * | ||
790 | * This function sends a command to the adapter using the correct write call. | ||
791 | * In the case of sis64, calculate the ioarcb size required. Then or in the | ||
792 | * appropriate bits. | ||
793 | * | ||
794 | * Return value: | ||
795 | * none | ||
796 | **/ | ||
797 | static void ipr_send_command(struct ipr_cmnd *ipr_cmd) | ||
798 | { | ||
799 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
800 | dma_addr_t send_dma_addr = ipr_cmd->dma_addr; | ||
801 | |||
802 | if (ioa_cfg->sis64) { | ||
803 | /* The default size is 256 bytes */ | ||
804 | send_dma_addr |= 0x1; | ||
805 | |||
806 | /* If the number of ioadls * size of ioadl > 128 bytes, | ||
807 | then use a 512 byte ioarcb */ | ||
808 | if (ipr_cmd->dma_use_sg * sizeof(struct ipr_ioadl64_desc) > 128 ) | ||
809 | send_dma_addr |= 0x4; | ||
810 | writeq(send_dma_addr, ioa_cfg->regs.ioarrin_reg); | ||
811 | } else | ||
812 | writel(send_dma_addr, ioa_cfg->regs.ioarrin_reg); | ||
813 | } | ||
814 | |||
815 | /** | ||
696 | * ipr_do_req - Send driver initiated requests. | 816 | * ipr_do_req - Send driver initiated requests. |
697 | * @ipr_cmd: ipr command struct | 817 | * @ipr_cmd: ipr command struct |
698 | * @done: done function | 818 | * @done: done function |
@@ -724,8 +844,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd, | |||
724 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); | 844 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); |
725 | 845 | ||
726 | mb(); | 846 | mb(); |
727 | writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), | 847 | |
728 | ioa_cfg->regs.ioarrin_reg); | 848 | ipr_send_command(ipr_cmd); |
729 | } | 849 | } |
730 | 850 | ||
731 | /** | 851 | /** |
@@ -747,6 +867,51 @@ static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd) | |||
747 | } | 867 | } |
748 | 868 | ||
749 | /** | 869 | /** |
870 | * ipr_init_ioadl - initialize the ioadl for the correct SIS type | ||
871 | * @ipr_cmd: ipr command struct | ||
872 | * @dma_addr: dma address | ||
873 | * @len: transfer length | ||
874 | * @flags: ioadl flag value | ||
875 | * | ||
876 | * This function initializes an ioadl in the case where there is only a single | ||
877 | * descriptor. | ||
878 | * | ||
879 | * Return value: | ||
880 | * nothing | ||
881 | **/ | ||
882 | static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr, | ||
883 | u32 len, int flags) | ||
884 | { | ||
885 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; | ||
886 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
887 | |||
888 | ipr_cmd->dma_use_sg = 1; | ||
889 | |||
890 | if (ipr_cmd->ioa_cfg->sis64) { | ||
891 | ioadl64->flags = cpu_to_be32(flags); | ||
892 | ioadl64->data_len = cpu_to_be32(len); | ||
893 | ioadl64->address = cpu_to_be64(dma_addr); | ||
894 | |||
895 | ipr_cmd->ioarcb.ioadl_len = | ||
896 | cpu_to_be32(sizeof(struct ipr_ioadl64_desc)); | ||
897 | ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len); | ||
898 | } else { | ||
899 | ioadl->flags_and_data_len = cpu_to_be32(flags | len); | ||
900 | ioadl->address = cpu_to_be32(dma_addr); | ||
901 | |||
902 | if (flags == IPR_IOADL_FLAGS_READ_LAST) { | ||
903 | ipr_cmd->ioarcb.read_ioadl_len = | ||
904 | cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
905 | ipr_cmd->ioarcb.read_data_transfer_length = cpu_to_be32(len); | ||
906 | } else { | ||
907 | ipr_cmd->ioarcb.ioadl_len = | ||
908 | cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
909 | ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len); | ||
910 | } | ||
911 | } | ||
912 | } | ||
913 | |||
914 | /** | ||
750 | * ipr_send_blocking_cmd - Send command and sleep on its completion. | 915 | * ipr_send_blocking_cmd - Send command and sleep on its completion. |
751 | * @ipr_cmd: ipr command struct | 916 | * @ipr_cmd: ipr command struct |
752 | * @timeout_func: function to invoke if command times out | 917 | * @timeout_func: function to invoke if command times out |
@@ -803,11 +968,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, | |||
803 | ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff; | 968 | ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff; |
804 | ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff; | 969 | ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff; |
805 | 970 | ||
806 | ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam)); | 971 | ipr_init_ioadl(ipr_cmd, hostrcb->hostrcb_dma, |
807 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 972 | sizeof(hostrcb->hcam), IPR_IOADL_FLAGS_READ_LAST); |
808 | ipr_cmd->ioadl[0].flags_and_data_len = | ||
809 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam)); | ||
810 | ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma); | ||
811 | 973 | ||
812 | if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE) | 974 | if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE) |
813 | ipr_cmd->done = ipr_process_ccn; | 975 | ipr_cmd->done = ipr_process_ccn; |
@@ -817,22 +979,54 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, | |||
817 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); | 979 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); |
818 | 980 | ||
819 | mb(); | 981 | mb(); |
820 | writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), | 982 | |
821 | ioa_cfg->regs.ioarrin_reg); | 983 | ipr_send_command(ipr_cmd); |
822 | } else { | 984 | } else { |
823 | list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); | 985 | list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); |
824 | } | 986 | } |
825 | } | 987 | } |
826 | 988 | ||
827 | /** | 989 | /** |
990 | * ipr_update_ata_class - Update the ata class in the resource entry | ||
991 | * @res: resource entry struct | ||
992 | * @proto: cfgte device bus protocol value | ||
993 | * | ||
994 | * Return value: | ||
995 | * none | ||
996 | **/ | ||
997 | static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int proto) | ||
998 | { | ||
999 | switch(proto) { | ||
1000 | case IPR_PROTO_SATA: | ||
1001 | case IPR_PROTO_SAS_STP: | ||
1002 | res->ata_class = ATA_DEV_ATA; | ||
1003 | break; | ||
1004 | case IPR_PROTO_SATA_ATAPI: | ||
1005 | case IPR_PROTO_SAS_STP_ATAPI: | ||
1006 | res->ata_class = ATA_DEV_ATAPI; | ||
1007 | break; | ||
1008 | default: | ||
1009 | res->ata_class = ATA_DEV_UNKNOWN; | ||
1010 | break; | ||
1011 | }; | ||
1012 | } | ||
1013 | |||
1014 | /** | ||
828 | * ipr_init_res_entry - Initialize a resource entry struct. | 1015 | * ipr_init_res_entry - Initialize a resource entry struct. |
829 | * @res: resource entry struct | 1016 | * @res: resource entry struct |
1017 | * @cfgtew: config table entry wrapper struct | ||
830 | * | 1018 | * |
831 | * Return value: | 1019 | * Return value: |
832 | * none | 1020 | * none |
833 | **/ | 1021 | **/ |
834 | static void ipr_init_res_entry(struct ipr_resource_entry *res) | 1022 | static void ipr_init_res_entry(struct ipr_resource_entry *res, |
1023 | struct ipr_config_table_entry_wrapper *cfgtew) | ||
835 | { | 1024 | { |
1025 | int found = 0; | ||
1026 | unsigned int proto; | ||
1027 | struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg; | ||
1028 | struct ipr_resource_entry *gscsi_res = NULL; | ||
1029 | |||
836 | res->needs_sync_complete = 0; | 1030 | res->needs_sync_complete = 0; |
837 | res->in_erp = 0; | 1031 | res->in_erp = 0; |
838 | res->add_to_ml = 0; | 1032 | res->add_to_ml = 0; |
@@ -840,6 +1034,205 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res) | |||
840 | res->resetting_device = 0; | 1034 | res->resetting_device = 0; |
841 | res->sdev = NULL; | 1035 | res->sdev = NULL; |
842 | res->sata_port = NULL; | 1036 | res->sata_port = NULL; |
1037 | |||
1038 | if (ioa_cfg->sis64) { | ||
1039 | proto = cfgtew->u.cfgte64->proto; | ||
1040 | res->res_flags = cfgtew->u.cfgte64->res_flags; | ||
1041 | res->qmodel = IPR_QUEUEING_MODEL64(res); | ||
1042 | res->type = cfgtew->u.cfgte64->res_type & 0x0f; | ||
1043 | |||
1044 | memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, | ||
1045 | sizeof(res->res_path)); | ||
1046 | |||
1047 | res->bus = 0; | ||
1048 | res->lun = scsilun_to_int(&res->dev_lun); | ||
1049 | |||
1050 | if (res->type == IPR_RES_TYPE_GENERIC_SCSI) { | ||
1051 | list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) { | ||
1052 | if (gscsi_res->dev_id == cfgtew->u.cfgte64->dev_id) { | ||
1053 | found = 1; | ||
1054 | res->target = gscsi_res->target; | ||
1055 | break; | ||
1056 | } | ||
1057 | } | ||
1058 | if (!found) { | ||
1059 | res->target = find_first_zero_bit(ioa_cfg->target_ids, | ||
1060 | ioa_cfg->max_devs_supported); | ||
1061 | set_bit(res->target, ioa_cfg->target_ids); | ||
1062 | } | ||
1063 | |||
1064 | memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun, | ||
1065 | sizeof(res->dev_lun.scsi_lun)); | ||
1066 | } else if (res->type == IPR_RES_TYPE_IOAFP) { | ||
1067 | res->bus = IPR_IOAFP_VIRTUAL_BUS; | ||
1068 | res->target = 0; | ||
1069 | } else if (res->type == IPR_RES_TYPE_ARRAY) { | ||
1070 | res->bus = IPR_ARRAY_VIRTUAL_BUS; | ||
1071 | res->target = find_first_zero_bit(ioa_cfg->array_ids, | ||
1072 | ioa_cfg->max_devs_supported); | ||
1073 | set_bit(res->target, ioa_cfg->array_ids); | ||
1074 | } else if (res->type == IPR_RES_TYPE_VOLUME_SET) { | ||
1075 | res->bus = IPR_VSET_VIRTUAL_BUS; | ||
1076 | res->target = find_first_zero_bit(ioa_cfg->vset_ids, | ||
1077 | ioa_cfg->max_devs_supported); | ||
1078 | set_bit(res->target, ioa_cfg->vset_ids); | ||
1079 | } else { | ||
1080 | res->target = find_first_zero_bit(ioa_cfg->target_ids, | ||
1081 | ioa_cfg->max_devs_supported); | ||
1082 | set_bit(res->target, ioa_cfg->target_ids); | ||
1083 | } | ||
1084 | } else { | ||
1085 | proto = cfgtew->u.cfgte->proto; | ||
1086 | res->qmodel = IPR_QUEUEING_MODEL(res); | ||
1087 | res->flags = cfgtew->u.cfgte->flags; | ||
1088 | if (res->flags & IPR_IS_IOA_RESOURCE) | ||
1089 | res->type = IPR_RES_TYPE_IOAFP; | ||
1090 | else | ||
1091 | res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f; | ||
1092 | |||
1093 | res->bus = cfgtew->u.cfgte->res_addr.bus; | ||
1094 | res->target = cfgtew->u.cfgte->res_addr.target; | ||
1095 | res->lun = cfgtew->u.cfgte->res_addr.lun; | ||
1096 | } | ||
1097 | |||
1098 | ipr_update_ata_class(res, proto); | ||
1099 | } | ||
1100 | |||
1101 | /** | ||
1102 | * ipr_is_same_device - Determine if two devices are the same. | ||
1103 | * @res: resource entry struct | ||
1104 | * @cfgtew: config table entry wrapper struct | ||
1105 | * | ||
1106 | * Return value: | ||
1107 | * 1 if the devices are the same / 0 otherwise | ||
1108 | **/ | ||
1109 | static int ipr_is_same_device(struct ipr_resource_entry *res, | ||
1110 | struct ipr_config_table_entry_wrapper *cfgtew) | ||
1111 | { | ||
1112 | if (res->ioa_cfg->sis64) { | ||
1113 | if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id, | ||
1114 | sizeof(cfgtew->u.cfgte64->dev_id)) && | ||
1115 | !memcmp(&res->lun, &cfgtew->u.cfgte64->lun, | ||
1116 | sizeof(cfgtew->u.cfgte64->lun))) { | ||
1117 | return 1; | ||
1118 | } | ||
1119 | } else { | ||
1120 | if (res->bus == cfgtew->u.cfgte->res_addr.bus && | ||
1121 | res->target == cfgtew->u.cfgte->res_addr.target && | ||
1122 | res->lun == cfgtew->u.cfgte->res_addr.lun) | ||
1123 | return 1; | ||
1124 | } | ||
1125 | |||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1129 | /** | ||
1130 | * ipr_format_resource_path - Format the resource path for printing. | ||
1131 | * @res_path: resource path | ||
1132 | * @buf: buffer | ||
1133 | * | ||
1134 | * Return value: | ||
1135 | * pointer to buffer | ||
1136 | **/ | ||
1137 | static char *ipr_format_resource_path(u8 *res_path, char *buffer) | ||
1138 | { | ||
1139 | int i; | ||
1140 | |||
1141 | sprintf(buffer, "%02X", res_path[0]); | ||
1142 | for (i=1; res_path[i] != 0xff; i++) | ||
1143 | sprintf(buffer, "%s-%02X", buffer, res_path[i]); | ||
1144 | |||
1145 | return buffer; | ||
1146 | } | ||
1147 | |||
1148 | /** | ||
1149 | * ipr_update_res_entry - Update the resource entry. | ||
1150 | * @res: resource entry struct | ||
1151 | * @cfgtew: config table entry wrapper struct | ||
1152 | * | ||
1153 | * Return value: | ||
1154 | * none | ||
1155 | **/ | ||
1156 | static void ipr_update_res_entry(struct ipr_resource_entry *res, | ||
1157 | struct ipr_config_table_entry_wrapper *cfgtew) | ||
1158 | { | ||
1159 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
1160 | unsigned int proto; | ||
1161 | int new_path = 0; | ||
1162 | |||
1163 | if (res->ioa_cfg->sis64) { | ||
1164 | res->flags = cfgtew->u.cfgte64->flags; | ||
1165 | res->res_flags = cfgtew->u.cfgte64->res_flags; | ||
1166 | res->type = cfgtew->u.cfgte64->res_type & 0x0f; | ||
1167 | |||
1168 | memcpy(&res->std_inq_data, &cfgtew->u.cfgte64->std_inq_data, | ||
1169 | sizeof(struct ipr_std_inq_data)); | ||
1170 | |||
1171 | res->qmodel = IPR_QUEUEING_MODEL64(res); | ||
1172 | proto = cfgtew->u.cfgte64->proto; | ||
1173 | res->res_handle = cfgtew->u.cfgte64->res_handle; | ||
1174 | res->dev_id = cfgtew->u.cfgte64->dev_id; | ||
1175 | |||
1176 | memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun, | ||
1177 | sizeof(res->dev_lun.scsi_lun)); | ||
1178 | |||
1179 | if (memcmp(res->res_path, &cfgtew->u.cfgte64->res_path, | ||
1180 | sizeof(res->res_path))) { | ||
1181 | memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, | ||
1182 | sizeof(res->res_path)); | ||
1183 | new_path = 1; | ||
1184 | } | ||
1185 | |||
1186 | if (res->sdev && new_path) | ||
1187 | sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n", | ||
1188 | ipr_format_resource_path(&res->res_path[0], &buffer[0])); | ||
1189 | } else { | ||
1190 | res->flags = cfgtew->u.cfgte->flags; | ||
1191 | if (res->flags & IPR_IS_IOA_RESOURCE) | ||
1192 | res->type = IPR_RES_TYPE_IOAFP; | ||
1193 | else | ||
1194 | res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f; | ||
1195 | |||
1196 | memcpy(&res->std_inq_data, &cfgtew->u.cfgte->std_inq_data, | ||
1197 | sizeof(struct ipr_std_inq_data)); | ||
1198 | |||
1199 | res->qmodel = IPR_QUEUEING_MODEL(res); | ||
1200 | proto = cfgtew->u.cfgte->proto; | ||
1201 | res->res_handle = cfgtew->u.cfgte->res_handle; | ||
1202 | } | ||
1203 | |||
1204 | ipr_update_ata_class(res, proto); | ||
1205 | } | ||
1206 | |||
1207 | /** | ||
1208 | * ipr_clear_res_target - Clear the bit in the bit map representing the target | ||
1209 | * for the resource. | ||
1210 | * @res: resource entry struct | ||
1211 | * @cfgtew: config table entry wrapper struct | ||
1212 | * | ||
1213 | * Return value: | ||
1214 | * none | ||
1215 | **/ | ||
1216 | static void ipr_clear_res_target(struct ipr_resource_entry *res) | ||
1217 | { | ||
1218 | struct ipr_resource_entry *gscsi_res = NULL; | ||
1219 | struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg; | ||
1220 | |||
1221 | if (!ioa_cfg->sis64) | ||
1222 | return; | ||
1223 | |||
1224 | if (res->bus == IPR_ARRAY_VIRTUAL_BUS) | ||
1225 | clear_bit(res->target, ioa_cfg->array_ids); | ||
1226 | else if (res->bus == IPR_VSET_VIRTUAL_BUS) | ||
1227 | clear_bit(res->target, ioa_cfg->vset_ids); | ||
1228 | else if (res->bus == 0 && res->type == IPR_RES_TYPE_GENERIC_SCSI) { | ||
1229 | list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) | ||
1230 | if (gscsi_res->dev_id == res->dev_id && gscsi_res != res) | ||
1231 | return; | ||
1232 | clear_bit(res->target, ioa_cfg->target_ids); | ||
1233 | |||
1234 | } else if (res->bus == 0) | ||
1235 | clear_bit(res->target, ioa_cfg->target_ids); | ||
843 | } | 1236 | } |
844 | 1237 | ||
845 | /** | 1238 | /** |
@@ -851,17 +1244,24 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res) | |||
851 | * none | 1244 | * none |
852 | **/ | 1245 | **/ |
853 | static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, | 1246 | static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, |
854 | struct ipr_hostrcb *hostrcb) | 1247 | struct ipr_hostrcb *hostrcb) |
855 | { | 1248 | { |
856 | struct ipr_resource_entry *res = NULL; | 1249 | struct ipr_resource_entry *res = NULL; |
857 | struct ipr_config_table_entry *cfgte; | 1250 | struct ipr_config_table_entry_wrapper cfgtew; |
1251 | __be32 cc_res_handle; | ||
1252 | |||
858 | u32 is_ndn = 1; | 1253 | u32 is_ndn = 1; |
859 | 1254 | ||
860 | cfgte = &hostrcb->hcam.u.ccn.cfgte; | 1255 | if (ioa_cfg->sis64) { |
1256 | cfgtew.u.cfgte64 = &hostrcb->hcam.u.ccn.u.cfgte64; | ||
1257 | cc_res_handle = cfgtew.u.cfgte64->res_handle; | ||
1258 | } else { | ||
1259 | cfgtew.u.cfgte = &hostrcb->hcam.u.ccn.u.cfgte; | ||
1260 | cc_res_handle = cfgtew.u.cfgte->res_handle; | ||
1261 | } | ||
861 | 1262 | ||
862 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 1263 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
863 | if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr, | 1264 | if (res->res_handle == cc_res_handle) { |
864 | sizeof(cfgte->res_addr))) { | ||
865 | is_ndn = 0; | 1265 | is_ndn = 0; |
866 | break; | 1266 | break; |
867 | } | 1267 | } |
@@ -879,20 +1279,22 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, | |||
879 | struct ipr_resource_entry, queue); | 1279 | struct ipr_resource_entry, queue); |
880 | 1280 | ||
881 | list_del(&res->queue); | 1281 | list_del(&res->queue); |
882 | ipr_init_res_entry(res); | 1282 | ipr_init_res_entry(res, &cfgtew); |
883 | list_add_tail(&res->queue, &ioa_cfg->used_res_q); | 1283 | list_add_tail(&res->queue, &ioa_cfg->used_res_q); |
884 | } | 1284 | } |
885 | 1285 | ||
886 | memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); | 1286 | ipr_update_res_entry(res, &cfgtew); |
887 | 1287 | ||
888 | if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { | 1288 | if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { |
889 | if (res->sdev) { | 1289 | if (res->sdev) { |
890 | res->del_from_ml = 1; | 1290 | res->del_from_ml = 1; |
891 | res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; | 1291 | res->res_handle = IPR_INVALID_RES_HANDLE; |
892 | if (ioa_cfg->allow_ml_add_del) | 1292 | if (ioa_cfg->allow_ml_add_del) |
893 | schedule_work(&ioa_cfg->work_q); | 1293 | schedule_work(&ioa_cfg->work_q); |
894 | } else | 1294 | } else { |
1295 | ipr_clear_res_target(res); | ||
895 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); | 1296 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); |
1297 | } | ||
896 | } else if (!res->sdev) { | 1298 | } else if (!res->sdev) { |
897 | res->add_to_ml = 1; | 1299 | res->add_to_ml = 1; |
898 | if (ioa_cfg->allow_ml_add_del) | 1300 | if (ioa_cfg->allow_ml_add_del) |
@@ -1044,8 +1446,12 @@ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd) | |||
1044 | static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, | 1446 | static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, |
1045 | struct ipr_hostrcb *hostrcb) | 1447 | struct ipr_hostrcb *hostrcb) |
1046 | { | 1448 | { |
1047 | struct ipr_hostrcb_type_12_error *error = | 1449 | struct ipr_hostrcb_type_12_error *error; |
1048 | &hostrcb->hcam.u.error.u.type_12_error; | 1450 | |
1451 | if (ioa_cfg->sis64) | ||
1452 | error = &hostrcb->hcam.u.error64.u.type_12_error; | ||
1453 | else | ||
1454 | error = &hostrcb->hcam.u.error.u.type_12_error; | ||
1049 | 1455 | ||
1050 | ipr_err("-----Current Configuration-----\n"); | 1456 | ipr_err("-----Current Configuration-----\n"); |
1051 | ipr_err("Cache Directory Card Information:\n"); | 1457 | ipr_err("Cache Directory Card Information:\n"); |
@@ -1138,6 +1544,48 @@ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1138 | } | 1544 | } |
1139 | 1545 | ||
1140 | /** | 1546 | /** |
1547 | * ipr_log_sis64_config_error - Log a device error. | ||
1548 | * @ioa_cfg: ioa config struct | ||
1549 | * @hostrcb: hostrcb struct | ||
1550 | * | ||
1551 | * Return value: | ||
1552 | * none | ||
1553 | **/ | ||
1554 | static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg, | ||
1555 | struct ipr_hostrcb *hostrcb) | ||
1556 | { | ||
1557 | int errors_logged, i; | ||
1558 | struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry; | ||
1559 | struct ipr_hostrcb_type_23_error *error; | ||
1560 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
1561 | |||
1562 | error = &hostrcb->hcam.u.error64.u.type_23_error; | ||
1563 | errors_logged = be32_to_cpu(error->errors_logged); | ||
1564 | |||
1565 | ipr_err("Device Errors Detected/Logged: %d/%d\n", | ||
1566 | be32_to_cpu(error->errors_detected), errors_logged); | ||
1567 | |||
1568 | dev_entry = error->dev; | ||
1569 | |||
1570 | for (i = 0; i < errors_logged; i++, dev_entry++) { | ||
1571 | ipr_err_separator; | ||
1572 | |||
1573 | ipr_err("Device %d : %s", i + 1, | ||
1574 | ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0])); | ||
1575 | ipr_log_ext_vpd(&dev_entry->vpd); | ||
1576 | |||
1577 | ipr_err("-----New Device Information-----\n"); | ||
1578 | ipr_log_ext_vpd(&dev_entry->new_vpd); | ||
1579 | |||
1580 | ipr_err("Cache Directory Card Information:\n"); | ||
1581 | ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd); | ||
1582 | |||
1583 | ipr_err("Adapter Card Information:\n"); | ||
1584 | ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd); | ||
1585 | } | ||
1586 | } | ||
1587 | |||
1588 | /** | ||
1141 | * ipr_log_config_error - Log a configuration error. | 1589 | * ipr_log_config_error - Log a configuration error. |
1142 | * @ioa_cfg: ioa config struct | 1590 | * @ioa_cfg: ioa config struct |
1143 | * @hostrcb: hostrcb struct | 1591 | * @hostrcb: hostrcb struct |
@@ -1331,7 +1779,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1331 | { | 1779 | { |
1332 | struct ipr_hostrcb_type_17_error *error; | 1780 | struct ipr_hostrcb_type_17_error *error; |
1333 | 1781 | ||
1334 | error = &hostrcb->hcam.u.error.u.type_17_error; | 1782 | if (ioa_cfg->sis64) |
1783 | error = &hostrcb->hcam.u.error64.u.type_17_error; | ||
1784 | else | ||
1785 | error = &hostrcb->hcam.u.error.u.type_17_error; | ||
1786 | |||
1335 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | 1787 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; |
1336 | strim(error->failure_reason); | 1788 | strim(error->failure_reason); |
1337 | 1789 | ||
@@ -1438,6 +1890,42 @@ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb, | |||
1438 | fabric->ioa_port, fabric->cascaded_expander, fabric->phy); | 1890 | fabric->ioa_port, fabric->cascaded_expander, fabric->phy); |
1439 | } | 1891 | } |
1440 | 1892 | ||
1893 | /** | ||
1894 | * ipr_log64_fabric_path - Log a fabric path error | ||
1895 | * @hostrcb: hostrcb struct | ||
1896 | * @fabric: fabric descriptor | ||
1897 | * | ||
1898 | * Return value: | ||
1899 | * none | ||
1900 | **/ | ||
1901 | static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb, | ||
1902 | struct ipr_hostrcb64_fabric_desc *fabric) | ||
1903 | { | ||
1904 | int i, j; | ||
1905 | u8 path_state = fabric->path_state; | ||
1906 | u8 active = path_state & IPR_PATH_ACTIVE_MASK; | ||
1907 | u8 state = path_state & IPR_PATH_STATE_MASK; | ||
1908 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
1909 | |||
1910 | for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) { | ||
1911 | if (path_active_desc[i].active != active) | ||
1912 | continue; | ||
1913 | |||
1914 | for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) { | ||
1915 | if (path_state_desc[j].state != state) | ||
1916 | continue; | ||
1917 | |||
1918 | ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n", | ||
1919 | path_active_desc[i].desc, path_state_desc[j].desc, | ||
1920 | ipr_format_resource_path(&fabric->res_path[0], &buffer[0])); | ||
1921 | return; | ||
1922 | } | ||
1923 | } | ||
1924 | |||
1925 | ipr_err("Path state=%02X Resource Path=%s\n", path_state, | ||
1926 | ipr_format_resource_path(&fabric->res_path[0], &buffer[0])); | ||
1927 | } | ||
1928 | |||
1441 | static const struct { | 1929 | static const struct { |
1442 | u8 type; | 1930 | u8 type; |
1443 | char *desc; | 1931 | char *desc; |
@@ -1547,6 +2035,49 @@ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb, | |||
1547 | } | 2035 | } |
1548 | 2036 | ||
1549 | /** | 2037 | /** |
2038 | * ipr_log64_path_elem - Log a fabric path element. | ||
2039 | * @hostrcb: hostrcb struct | ||
2040 | * @cfg: fabric path element struct | ||
2041 | * | ||
2042 | * Return value: | ||
2043 | * none | ||
2044 | **/ | ||
2045 | static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb, | ||
2046 | struct ipr_hostrcb64_config_element *cfg) | ||
2047 | { | ||
2048 | int i, j; | ||
2049 | u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK; | ||
2050 | u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK; | ||
2051 | u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK; | ||
2052 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
2053 | |||
2054 | if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64) | ||
2055 | return; | ||
2056 | |||
2057 | for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) { | ||
2058 | if (path_type_desc[i].type != type) | ||
2059 | continue; | ||
2060 | |||
2061 | for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) { | ||
2062 | if (path_status_desc[j].status != status) | ||
2063 | continue; | ||
2064 | |||
2065 | ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n", | ||
2066 | path_status_desc[j].desc, path_type_desc[i].desc, | ||
2067 | ipr_format_resource_path(&cfg->res_path[0], &buffer[0]), | ||
2068 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
2069 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
2070 | return; | ||
2071 | } | ||
2072 | } | ||
2073 | ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s " | ||
2074 | "WWN=%08X%08X\n", cfg->type_status, | ||
2075 | ipr_format_resource_path(&cfg->res_path[0], &buffer[0]), | ||
2076 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
2077 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
2078 | } | ||
2079 | |||
2080 | /** | ||
1550 | * ipr_log_fabric_error - Log a fabric error. | 2081 | * ipr_log_fabric_error - Log a fabric error. |
1551 | * @ioa_cfg: ioa config struct | 2082 | * @ioa_cfg: ioa config struct |
1552 | * @hostrcb: hostrcb struct | 2083 | * @hostrcb: hostrcb struct |
@@ -1584,6 +2115,96 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1584 | } | 2115 | } |
1585 | 2116 | ||
1586 | /** | 2117 | /** |
2118 | * ipr_log_sis64_array_error - Log a sis64 array error. | ||
2119 | * @ioa_cfg: ioa config struct | ||
2120 | * @hostrcb: hostrcb struct | ||
2121 | * | ||
2122 | * Return value: | ||
2123 | * none | ||
2124 | **/ | ||
2125 | static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg, | ||
2126 | struct ipr_hostrcb *hostrcb) | ||
2127 | { | ||
2128 | int i, num_entries; | ||
2129 | struct ipr_hostrcb_type_24_error *error; | ||
2130 | struct ipr_hostrcb64_array_data_entry *array_entry; | ||
2131 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
2132 | const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' }; | ||
2133 | |||
2134 | error = &hostrcb->hcam.u.error64.u.type_24_error; | ||
2135 | |||
2136 | ipr_err_separator; | ||
2137 | |||
2138 | ipr_err("RAID %s Array Configuration: %s\n", | ||
2139 | error->protection_level, | ||
2140 | ipr_format_resource_path(&error->last_res_path[0], &buffer[0])); | ||
2141 | |||
2142 | ipr_err_separator; | ||
2143 | |||
2144 | array_entry = error->array_member; | ||
2145 | num_entries = min_t(u32, be32_to_cpu(error->num_entries), | ||
2146 | sizeof(error->array_member)); | ||
2147 | |||
2148 | for (i = 0; i < num_entries; i++, array_entry++) { | ||
2149 | |||
2150 | if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN)) | ||
2151 | continue; | ||
2152 | |||
2153 | if (error->exposed_mode_adn == i) | ||
2154 | ipr_err("Exposed Array Member %d:\n", i); | ||
2155 | else | ||
2156 | ipr_err("Array Member %d:\n", i); | ||
2157 | |||
2158 | ipr_err("Array Member %d:\n", i); | ||
2159 | ipr_log_ext_vpd(&array_entry->vpd); | ||
2160 | ipr_err("Current Location: %s", | ||
2161 | ipr_format_resource_path(&array_entry->res_path[0], &buffer[0])); | ||
2162 | ipr_err("Expected Location: %s", | ||
2163 | ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0])); | ||
2164 | |||
2165 | ipr_err_separator; | ||
2166 | } | ||
2167 | } | ||
2168 | |||
2169 | /** | ||
2170 | * ipr_log_sis64_fabric_error - Log a sis64 fabric error. | ||
2171 | * @ioa_cfg: ioa config struct | ||
2172 | * @hostrcb: hostrcb struct | ||
2173 | * | ||
2174 | * Return value: | ||
2175 | * none | ||
2176 | **/ | ||
2177 | static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg, | ||
2178 | struct ipr_hostrcb *hostrcb) | ||
2179 | { | ||
2180 | struct ipr_hostrcb_type_30_error *error; | ||
2181 | struct ipr_hostrcb64_fabric_desc *fabric; | ||
2182 | struct ipr_hostrcb64_config_element *cfg; | ||
2183 | int i, add_len; | ||
2184 | |||
2185 | error = &hostrcb->hcam.u.error64.u.type_30_error; | ||
2186 | |||
2187 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | ||
2188 | ipr_hcam_err(hostrcb, "%s\n", error->failure_reason); | ||
2189 | |||
2190 | add_len = be32_to_cpu(hostrcb->hcam.length) - | ||
2191 | (offsetof(struct ipr_hostrcb64_error, u) + | ||
2192 | offsetof(struct ipr_hostrcb_type_30_error, desc)); | ||
2193 | |||
2194 | for (i = 0, fabric = error->desc; i < error->num_entries; i++) { | ||
2195 | ipr_log64_fabric_path(hostrcb, fabric); | ||
2196 | for_each_fabric_cfg(fabric, cfg) | ||
2197 | ipr_log64_path_elem(hostrcb, cfg); | ||
2198 | |||
2199 | add_len -= be16_to_cpu(fabric->length); | ||
2200 | fabric = (struct ipr_hostrcb64_fabric_desc *) | ||
2201 | ((unsigned long)fabric + be16_to_cpu(fabric->length)); | ||
2202 | } | ||
2203 | |||
2204 | ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len); | ||
2205 | } | ||
2206 | |||
2207 | /** | ||
1587 | * ipr_log_generic_error - Log an adapter error. | 2208 | * ipr_log_generic_error - Log an adapter error. |
1588 | * @ioa_cfg: ioa config struct | 2209 | * @ioa_cfg: ioa config struct |
1589 | * @hostrcb: hostrcb struct | 2210 | * @hostrcb: hostrcb struct |
@@ -1642,13 +2263,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
1642 | if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST) | 2263 | if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST) |
1643 | dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n"); | 2264 | dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n"); |
1644 | 2265 | ||
1645 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); | 2266 | if (ioa_cfg->sis64) |
2267 | ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc); | ||
2268 | else | ||
2269 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); | ||
1646 | 2270 | ||
1647 | if (ioasc == IPR_IOASC_BUS_WAS_RESET || | 2271 | if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET || |
1648 | ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) { | 2272 | ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) { |
1649 | /* Tell the midlayer we had a bus reset so it will handle the UA properly */ | 2273 | /* Tell the midlayer we had a bus reset so it will handle the UA properly */ |
1650 | scsi_report_bus_reset(ioa_cfg->host, | 2274 | scsi_report_bus_reset(ioa_cfg->host, |
1651 | hostrcb->hcam.u.error.failing_dev_res_addr.bus); | 2275 | hostrcb->hcam.u.error.fd_res_addr.bus); |
1652 | } | 2276 | } |
1653 | 2277 | ||
1654 | error_index = ipr_get_error(ioasc); | 2278 | error_index = ipr_get_error(ioasc); |
@@ -1696,6 +2320,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
1696 | case IPR_HOST_RCB_OVERLAY_ID_20: | 2320 | case IPR_HOST_RCB_OVERLAY_ID_20: |
1697 | ipr_log_fabric_error(ioa_cfg, hostrcb); | 2321 | ipr_log_fabric_error(ioa_cfg, hostrcb); |
1698 | break; | 2322 | break; |
2323 | case IPR_HOST_RCB_OVERLAY_ID_23: | ||
2324 | ipr_log_sis64_config_error(ioa_cfg, hostrcb); | ||
2325 | break; | ||
2326 | case IPR_HOST_RCB_OVERLAY_ID_24: | ||
2327 | case IPR_HOST_RCB_OVERLAY_ID_26: | ||
2328 | ipr_log_sis64_array_error(ioa_cfg, hostrcb); | ||
2329 | break; | ||
2330 | case IPR_HOST_RCB_OVERLAY_ID_30: | ||
2331 | ipr_log_sis64_fabric_error(ioa_cfg, hostrcb); | ||
2332 | break; | ||
1699 | case IPR_HOST_RCB_OVERLAY_ID_1: | 2333 | case IPR_HOST_RCB_OVERLAY_ID_1: |
1700 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: | 2334 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: |
1701 | default: | 2335 | default: |
@@ -1720,7 +2354,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) | |||
1720 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 2354 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
1721 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; | 2355 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; |
1722 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 2356 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); |
1723 | u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); | 2357 | u32 fd_ioasc; |
2358 | |||
2359 | if (ioa_cfg->sis64) | ||
2360 | fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc); | ||
2361 | else | ||
2362 | fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); | ||
1724 | 2363 | ||
1725 | list_del(&hostrcb->queue); | 2364 | list_del(&hostrcb->queue); |
1726 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | 2365 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); |
@@ -1845,12 +2484,14 @@ static const struct ipr_ses_table_entry * | |||
1845 | ipr_find_ses_entry(struct ipr_resource_entry *res) | 2484 | ipr_find_ses_entry(struct ipr_resource_entry *res) |
1846 | { | 2485 | { |
1847 | int i, j, matches; | 2486 | int i, j, matches; |
2487 | struct ipr_std_inq_vpids *vpids; | ||
1848 | const struct ipr_ses_table_entry *ste = ipr_ses_table; | 2488 | const struct ipr_ses_table_entry *ste = ipr_ses_table; |
1849 | 2489 | ||
1850 | for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) { | 2490 | for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) { |
1851 | for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) { | 2491 | for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) { |
1852 | if (ste->compare_product_id_byte[j] == 'X') { | 2492 | if (ste->compare_product_id_byte[j] == 'X') { |
1853 | if (res->cfgte.std_inq_data.vpids.product_id[j] == ste->product_id[j]) | 2493 | vpids = &res->std_inq_data.vpids; |
2494 | if (vpids->product_id[j] == ste->product_id[j]) | ||
1854 | matches++; | 2495 | matches++; |
1855 | else | 2496 | else |
1856 | break; | 2497 | break; |
@@ -1885,10 +2526,10 @@ static u32 ipr_get_max_scsi_speed(struct ipr_ioa_cfg *ioa_cfg, u8 bus, u8 bus_wi | |||
1885 | 2526 | ||
1886 | /* Loop through each config table entry in the config table buffer */ | 2527 | /* Loop through each config table entry in the config table buffer */ |
1887 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 2528 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
1888 | if (!(IPR_IS_SES_DEVICE(res->cfgte.std_inq_data))) | 2529 | if (!(IPR_IS_SES_DEVICE(res->std_inq_data))) |
1889 | continue; | 2530 | continue; |
1890 | 2531 | ||
1891 | if (bus != res->cfgte.res_addr.bus) | 2532 | if (bus != res->bus) |
1892 | continue; | 2533 | continue; |
1893 | 2534 | ||
1894 | if (!(ste = ipr_find_ses_entry(res))) | 2535 | if (!(ste = ipr_find_ses_entry(res))) |
@@ -1934,6 +2575,31 @@ static int ipr_wait_iodbg_ack(struct ipr_ioa_cfg *ioa_cfg, int max_delay) | |||
1934 | } | 2575 | } |
1935 | 2576 | ||
1936 | /** | 2577 | /** |
2578 | * ipr_get_sis64_dump_data_section - Dump IOA memory | ||
2579 | * @ioa_cfg: ioa config struct | ||
2580 | * @start_addr: adapter address to dump | ||
2581 | * @dest: destination kernel buffer | ||
2582 | * @length_in_words: length to dump in 4 byte words | ||
2583 | * | ||
2584 | * Return value: | ||
2585 | * 0 on success | ||
2586 | **/ | ||
2587 | static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg, | ||
2588 | u32 start_addr, | ||
2589 | __be32 *dest, u32 length_in_words) | ||
2590 | { | ||
2591 | int i; | ||
2592 | |||
2593 | for (i = 0; i < length_in_words; i++) { | ||
2594 | writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg); | ||
2595 | *dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg)); | ||
2596 | dest++; | ||
2597 | } | ||
2598 | |||
2599 | return 0; | ||
2600 | } | ||
2601 | |||
2602 | /** | ||
1937 | * ipr_get_ldump_data_section - Dump IOA memory | 2603 | * ipr_get_ldump_data_section - Dump IOA memory |
1938 | * @ioa_cfg: ioa config struct | 2604 | * @ioa_cfg: ioa config struct |
1939 | * @start_addr: adapter address to dump | 2605 | * @start_addr: adapter address to dump |
@@ -1950,9 +2616,13 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
1950 | volatile u32 temp_pcii_reg; | 2616 | volatile u32 temp_pcii_reg; |
1951 | int i, delay = 0; | 2617 | int i, delay = 0; |
1952 | 2618 | ||
2619 | if (ioa_cfg->sis64) | ||
2620 | return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr, | ||
2621 | dest, length_in_words); | ||
2622 | |||
1953 | /* Write IOA interrupt reg starting LDUMP state */ | 2623 | /* Write IOA interrupt reg starting LDUMP state */ |
1954 | writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), | 2624 | writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), |
1955 | ioa_cfg->regs.set_uproc_interrupt_reg); | 2625 | ioa_cfg->regs.set_uproc_interrupt_reg32); |
1956 | 2626 | ||
1957 | /* Wait for IO debug acknowledge */ | 2627 | /* Wait for IO debug acknowledge */ |
1958 | if (ipr_wait_iodbg_ack(ioa_cfg, | 2628 | if (ipr_wait_iodbg_ack(ioa_cfg, |
@@ -1971,7 +2641,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
1971 | 2641 | ||
1972 | /* Signal address valid - clear IOA Reset alert */ | 2642 | /* Signal address valid - clear IOA Reset alert */ |
1973 | writel(IPR_UPROCI_RESET_ALERT, | 2643 | writel(IPR_UPROCI_RESET_ALERT, |
1974 | ioa_cfg->regs.clr_uproc_interrupt_reg); | 2644 | ioa_cfg->regs.clr_uproc_interrupt_reg32); |
1975 | 2645 | ||
1976 | for (i = 0; i < length_in_words; i++) { | 2646 | for (i = 0; i < length_in_words; i++) { |
1977 | /* Wait for IO debug acknowledge */ | 2647 | /* Wait for IO debug acknowledge */ |
@@ -1996,10 +2666,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
1996 | 2666 | ||
1997 | /* Signal end of block transfer. Set reset alert then clear IO debug ack */ | 2667 | /* Signal end of block transfer. Set reset alert then clear IO debug ack */ |
1998 | writel(IPR_UPROCI_RESET_ALERT, | 2668 | writel(IPR_UPROCI_RESET_ALERT, |
1999 | ioa_cfg->regs.set_uproc_interrupt_reg); | 2669 | ioa_cfg->regs.set_uproc_interrupt_reg32); |
2000 | 2670 | ||
2001 | writel(IPR_UPROCI_IO_DEBUG_ALERT, | 2671 | writel(IPR_UPROCI_IO_DEBUG_ALERT, |
2002 | ioa_cfg->regs.clr_uproc_interrupt_reg); | 2672 | ioa_cfg->regs.clr_uproc_interrupt_reg32); |
2003 | 2673 | ||
2004 | /* Signal dump data received - Clear IO debug Ack */ | 2674 | /* Signal dump data received - Clear IO debug Ack */ |
2005 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, | 2675 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, |
@@ -2008,7 +2678,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
2008 | /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ | 2678 | /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ |
2009 | while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { | 2679 | while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { |
2010 | temp_pcii_reg = | 2680 | temp_pcii_reg = |
2011 | readl(ioa_cfg->regs.sense_uproc_interrupt_reg); | 2681 | readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); |
2012 | 2682 | ||
2013 | if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) | 2683 | if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) |
2014 | return 0; | 2684 | return 0; |
@@ -2207,6 +2877,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2207 | u32 num_entries, start_off, end_off; | 2877 | u32 num_entries, start_off, end_off; |
2208 | u32 bytes_to_copy, bytes_copied, rc; | 2878 | u32 bytes_to_copy, bytes_copied, rc; |
2209 | struct ipr_sdt *sdt; | 2879 | struct ipr_sdt *sdt; |
2880 | int valid = 1; | ||
2210 | int i; | 2881 | int i; |
2211 | 2882 | ||
2212 | ENTER; | 2883 | ENTER; |
@@ -2220,7 +2891,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2220 | 2891 | ||
2221 | start_addr = readl(ioa_cfg->ioa_mailbox); | 2892 | start_addr = readl(ioa_cfg->ioa_mailbox); |
2222 | 2893 | ||
2223 | if (!ipr_sdt_is_fmt2(start_addr)) { | 2894 | if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) { |
2224 | dev_err(&ioa_cfg->pdev->dev, | 2895 | dev_err(&ioa_cfg->pdev->dev, |
2225 | "Invalid dump table format: %lx\n", start_addr); | 2896 | "Invalid dump table format: %lx\n", start_addr); |
2226 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 2897 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
@@ -2249,7 +2920,6 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2249 | 2920 | ||
2250 | /* IOA Dump entry */ | 2921 | /* IOA Dump entry */ |
2251 | ipr_init_dump_entry_hdr(&ioa_dump->hdr); | 2922 | ipr_init_dump_entry_hdr(&ioa_dump->hdr); |
2252 | ioa_dump->format = IPR_SDT_FMT2; | ||
2253 | ioa_dump->hdr.len = 0; | 2923 | ioa_dump->hdr.len = 0; |
2254 | ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY; | 2924 | ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY; |
2255 | ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID; | 2925 | ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID; |
@@ -2264,7 +2934,8 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2264 | sizeof(struct ipr_sdt) / sizeof(__be32)); | 2934 | sizeof(struct ipr_sdt) / sizeof(__be32)); |
2265 | 2935 | ||
2266 | /* Smart Dump table is ready to use and the first entry is valid */ | 2936 | /* Smart Dump table is ready to use and the first entry is valid */ |
2267 | if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) { | 2937 | if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) && |
2938 | (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) { | ||
2268 | dev_err(&ioa_cfg->pdev->dev, | 2939 | dev_err(&ioa_cfg->pdev->dev, |
2269 | "Dump of IOA failed. Dump table not valid: %d, %X.\n", | 2940 | "Dump of IOA failed. Dump table not valid: %d, %X.\n", |
2270 | rc, be32_to_cpu(sdt->hdr.state)); | 2941 | rc, be32_to_cpu(sdt->hdr.state)); |
@@ -2288,12 +2959,19 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2288 | } | 2959 | } |
2289 | 2960 | ||
2290 | if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) { | 2961 | if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) { |
2291 | sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset); | 2962 | sdt_word = be32_to_cpu(sdt->entry[i].start_token); |
2292 | start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK; | 2963 | if (ioa_cfg->sis64) |
2293 | end_off = be32_to_cpu(sdt->entry[i].end_offset); | 2964 | bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token); |
2294 | 2965 | else { | |
2295 | if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) { | 2966 | start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK; |
2296 | bytes_to_copy = end_off - start_off; | 2967 | end_off = be32_to_cpu(sdt->entry[i].end_token); |
2968 | |||
2969 | if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) | ||
2970 | bytes_to_copy = end_off - start_off; | ||
2971 | else | ||
2972 | valid = 0; | ||
2973 | } | ||
2974 | if (valid) { | ||
2297 | if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) { | 2975 | if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) { |
2298 | sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY; | 2976 | sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY; |
2299 | continue; | 2977 | continue; |
@@ -2422,9 +3100,9 @@ restart: | |||
2422 | 3100 | ||
2423 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 3101 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
2424 | if (res->add_to_ml) { | 3102 | if (res->add_to_ml) { |
2425 | bus = res->cfgte.res_addr.bus; | 3103 | bus = res->bus; |
2426 | target = res->cfgte.res_addr.target; | 3104 | target = res->target; |
2427 | lun = res->cfgte.res_addr.lun; | 3105 | lun = res->lun; |
2428 | res->add_to_ml = 0; | 3106 | res->add_to_ml = 0; |
2429 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 3107 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
2430 | scsi_add_device(ioa_cfg->host, bus, target, lun); | 3108 | scsi_add_device(ioa_cfg->host, bus, target, lun); |
@@ -2478,105 +3156,6 @@ static struct bin_attribute ipr_trace_attr = { | |||
2478 | }; | 3156 | }; |
2479 | #endif | 3157 | #endif |
2480 | 3158 | ||
2481 | static const struct { | ||
2482 | enum ipr_cache_state state; | ||
2483 | char *name; | ||
2484 | } cache_state [] = { | ||
2485 | { CACHE_NONE, "none" }, | ||
2486 | { CACHE_DISABLED, "disabled" }, | ||
2487 | { CACHE_ENABLED, "enabled" } | ||
2488 | }; | ||
2489 | |||
2490 | /** | ||
2491 | * ipr_show_write_caching - Show the write caching attribute | ||
2492 | * @dev: device struct | ||
2493 | * @buf: buffer | ||
2494 | * | ||
2495 | * Return value: | ||
2496 | * number of bytes printed to buffer | ||
2497 | **/ | ||
2498 | static ssize_t ipr_show_write_caching(struct device *dev, | ||
2499 | struct device_attribute *attr, char *buf) | ||
2500 | { | ||
2501 | struct Scsi_Host *shost = class_to_shost(dev); | ||
2502 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; | ||
2503 | unsigned long lock_flags = 0; | ||
2504 | int i, len = 0; | ||
2505 | |||
2506 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
2507 | for (i = 0; i < ARRAY_SIZE(cache_state); i++) { | ||
2508 | if (cache_state[i].state == ioa_cfg->cache_state) { | ||
2509 | len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name); | ||
2510 | break; | ||
2511 | } | ||
2512 | } | ||
2513 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2514 | return len; | ||
2515 | } | ||
2516 | |||
2517 | |||
2518 | /** | ||
2519 | * ipr_store_write_caching - Enable/disable adapter write cache | ||
2520 | * @dev: device struct | ||
2521 | * @buf: buffer | ||
2522 | * @count: buffer size | ||
2523 | * | ||
2524 | * This function will enable/disable adapter write cache. | ||
2525 | * | ||
2526 | * Return value: | ||
2527 | * count on success / other on failure | ||
2528 | **/ | ||
2529 | static ssize_t ipr_store_write_caching(struct device *dev, | ||
2530 | struct device_attribute *attr, | ||
2531 | const char *buf, size_t count) | ||
2532 | { | ||
2533 | struct Scsi_Host *shost = class_to_shost(dev); | ||
2534 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; | ||
2535 | unsigned long lock_flags = 0; | ||
2536 | enum ipr_cache_state new_state = CACHE_INVALID; | ||
2537 | int i; | ||
2538 | |||
2539 | if (!capable(CAP_SYS_ADMIN)) | ||
2540 | return -EACCES; | ||
2541 | if (ioa_cfg->cache_state == CACHE_NONE) | ||
2542 | return -EINVAL; | ||
2543 | |||
2544 | for (i = 0; i < ARRAY_SIZE(cache_state); i++) { | ||
2545 | if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) { | ||
2546 | new_state = cache_state[i].state; | ||
2547 | break; | ||
2548 | } | ||
2549 | } | ||
2550 | |||
2551 | if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED) | ||
2552 | return -EINVAL; | ||
2553 | |||
2554 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
2555 | if (ioa_cfg->cache_state == new_state) { | ||
2556 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2557 | return count; | ||
2558 | } | ||
2559 | |||
2560 | ioa_cfg->cache_state = new_state; | ||
2561 | dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n", | ||
2562 | new_state == CACHE_ENABLED ? "Enabling" : "Disabling"); | ||
2563 | if (!ioa_cfg->in_reset_reload) | ||
2564 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); | ||
2565 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2566 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); | ||
2567 | |||
2568 | return count; | ||
2569 | } | ||
2570 | |||
2571 | static struct device_attribute ipr_ioa_cache_attr = { | ||
2572 | .attr = { | ||
2573 | .name = "write_cache", | ||
2574 | .mode = S_IRUGO | S_IWUSR, | ||
2575 | }, | ||
2576 | .show = ipr_show_write_caching, | ||
2577 | .store = ipr_store_write_caching | ||
2578 | }; | ||
2579 | |||
2580 | /** | 3159 | /** |
2581 | * ipr_show_fw_version - Show the firmware version | 3160 | * ipr_show_fw_version - Show the firmware version |
2582 | * @dev: class device struct | 3161 | * @dev: class device struct |
@@ -2976,6 +3555,37 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, | |||
2976 | } | 3555 | } |
2977 | 3556 | ||
2978 | /** | 3557 | /** |
3558 | * ipr_build_ucode_ioadl64 - Build a microcode download IOADL | ||
3559 | * @ipr_cmd: ipr command struct | ||
3560 | * @sglist: scatter/gather list | ||
3561 | * | ||
3562 | * Builds a microcode download IOA data list (IOADL). | ||
3563 | * | ||
3564 | **/ | ||
3565 | static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd, | ||
3566 | struct ipr_sglist *sglist) | ||
3567 | { | ||
3568 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | ||
3569 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
3570 | struct scatterlist *scatterlist = sglist->scatterlist; | ||
3571 | int i; | ||
3572 | |||
3573 | ipr_cmd->dma_use_sg = sglist->num_dma_sg; | ||
3574 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | ||
3575 | ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len); | ||
3576 | |||
3577 | ioarcb->ioadl_len = | ||
3578 | cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); | ||
3579 | for (i = 0; i < ipr_cmd->dma_use_sg; i++) { | ||
3580 | ioadl64[i].flags = cpu_to_be32(IPR_IOADL_FLAGS_WRITE); | ||
3581 | ioadl64[i].data_len = cpu_to_be32(sg_dma_len(&scatterlist[i])); | ||
3582 | ioadl64[i].address = cpu_to_be64(sg_dma_address(&scatterlist[i])); | ||
3583 | } | ||
3584 | |||
3585 | ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); | ||
3586 | } | ||
3587 | |||
3588 | /** | ||
2979 | * ipr_build_ucode_ioadl - Build a microcode download IOADL | 3589 | * ipr_build_ucode_ioadl - Build a microcode download IOADL |
2980 | * @ipr_cmd: ipr command struct | 3590 | * @ipr_cmd: ipr command struct |
2981 | * @sglist: scatter/gather list | 3591 | * @sglist: scatter/gather list |
@@ -2987,14 +3597,15 @@ static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd, | |||
2987 | struct ipr_sglist *sglist) | 3597 | struct ipr_sglist *sglist) |
2988 | { | 3598 | { |
2989 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 3599 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
2990 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | 3600 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; |
2991 | struct scatterlist *scatterlist = sglist->scatterlist; | 3601 | struct scatterlist *scatterlist = sglist->scatterlist; |
2992 | int i; | 3602 | int i; |
2993 | 3603 | ||
2994 | ipr_cmd->dma_use_sg = sglist->num_dma_sg; | 3604 | ipr_cmd->dma_use_sg = sglist->num_dma_sg; |
2995 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 3605 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
2996 | ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len); | 3606 | ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len); |
2997 | ioarcb->write_ioadl_len = | 3607 | |
3608 | ioarcb->ioadl_len = | ||
2998 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 3609 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
2999 | 3610 | ||
3000 | for (i = 0; i < ipr_cmd->dma_use_sg; i++) { | 3611 | for (i = 0; i < ipr_cmd->dma_use_sg; i++) { |
@@ -3146,7 +3757,6 @@ static struct device_attribute *ipr_ioa_attrs[] = { | |||
3146 | &ipr_ioa_state_attr, | 3757 | &ipr_ioa_state_attr, |
3147 | &ipr_ioa_reset_attr, | 3758 | &ipr_ioa_reset_attr, |
3148 | &ipr_update_fw_attr, | 3759 | &ipr_update_fw_attr, |
3149 | &ipr_ioa_cache_attr, | ||
3150 | NULL, | 3760 | NULL, |
3151 | }; | 3761 | }; |
3152 | 3762 | ||
@@ -3450,7 +4060,7 @@ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribu | |||
3450 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 4060 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
3451 | res = (struct ipr_resource_entry *)sdev->hostdata; | 4061 | res = (struct ipr_resource_entry *)sdev->hostdata; |
3452 | if (res) | 4062 | if (res) |
3453 | len = snprintf(buf, PAGE_SIZE, "%08X\n", res->cfgte.res_handle); | 4063 | len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle); |
3454 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4064 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
3455 | return len; | 4065 | return len; |
3456 | } | 4066 | } |
@@ -3463,8 +4073,43 @@ static struct device_attribute ipr_adapter_handle_attr = { | |||
3463 | .show = ipr_show_adapter_handle | 4073 | .show = ipr_show_adapter_handle |
3464 | }; | 4074 | }; |
3465 | 4075 | ||
4076 | /** | ||
4077 | * ipr_show_resource_path - Show the resource path for this device. | ||
4078 | * @dev: device struct | ||
4079 | * @buf: buffer | ||
4080 | * | ||
4081 | * Return value: | ||
4082 | * number of bytes printed to buffer | ||
4083 | **/ | ||
4084 | static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf) | ||
4085 | { | ||
4086 | struct scsi_device *sdev = to_scsi_device(dev); | ||
4087 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; | ||
4088 | struct ipr_resource_entry *res; | ||
4089 | unsigned long lock_flags = 0; | ||
4090 | ssize_t len = -ENXIO; | ||
4091 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
4092 | |||
4093 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
4094 | res = (struct ipr_resource_entry *)sdev->hostdata; | ||
4095 | if (res) | ||
4096 | len = snprintf(buf, PAGE_SIZE, "%s\n", | ||
4097 | ipr_format_resource_path(&res->res_path[0], &buffer[0])); | ||
4098 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4099 | return len; | ||
4100 | } | ||
4101 | |||
4102 | static struct device_attribute ipr_resource_path_attr = { | ||
4103 | .attr = { | ||
4104 | .name = "resource_path", | ||
4105 | .mode = S_IRUSR, | ||
4106 | }, | ||
4107 | .show = ipr_show_resource_path | ||
4108 | }; | ||
4109 | |||
3466 | static struct device_attribute *ipr_dev_attrs[] = { | 4110 | static struct device_attribute *ipr_dev_attrs[] = { |
3467 | &ipr_adapter_handle_attr, | 4111 | &ipr_adapter_handle_attr, |
4112 | &ipr_resource_path_attr, | ||
3468 | NULL, | 4113 | NULL, |
3469 | }; | 4114 | }; |
3470 | 4115 | ||
@@ -3517,9 +4162,9 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget) | |||
3517 | struct ipr_resource_entry *res; | 4162 | struct ipr_resource_entry *res; |
3518 | 4163 | ||
3519 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 4164 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
3520 | if ((res->cfgte.res_addr.bus == starget->channel) && | 4165 | if ((res->bus == starget->channel) && |
3521 | (res->cfgte.res_addr.target == starget->id) && | 4166 | (res->target == starget->id) && |
3522 | (res->cfgte.res_addr.lun == 0)) { | 4167 | (res->lun == 0)) { |
3523 | return res; | 4168 | return res; |
3524 | } | 4169 | } |
3525 | } | 4170 | } |
@@ -3589,6 +4234,17 @@ static int ipr_target_alloc(struct scsi_target *starget) | |||
3589 | static void ipr_target_destroy(struct scsi_target *starget) | 4234 | static void ipr_target_destroy(struct scsi_target *starget) |
3590 | { | 4235 | { |
3591 | struct ipr_sata_port *sata_port = starget->hostdata; | 4236 | struct ipr_sata_port *sata_port = starget->hostdata; |
4237 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | ||
4238 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; | ||
4239 | |||
4240 | if (ioa_cfg->sis64) { | ||
4241 | if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) | ||
4242 | clear_bit(starget->id, ioa_cfg->array_ids); | ||
4243 | else if (starget->channel == IPR_VSET_VIRTUAL_BUS) | ||
4244 | clear_bit(starget->id, ioa_cfg->vset_ids); | ||
4245 | else if (starget->channel == 0) | ||
4246 | clear_bit(starget->id, ioa_cfg->target_ids); | ||
4247 | } | ||
3592 | 4248 | ||
3593 | if (sata_port) { | 4249 | if (sata_port) { |
3594 | starget->hostdata = NULL; | 4250 | starget->hostdata = NULL; |
@@ -3610,9 +4266,9 @@ static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev) | |||
3610 | struct ipr_resource_entry *res; | 4266 | struct ipr_resource_entry *res; |
3611 | 4267 | ||
3612 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 4268 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
3613 | if ((res->cfgte.res_addr.bus == sdev->channel) && | 4269 | if ((res->bus == sdev->channel) && |
3614 | (res->cfgte.res_addr.target == sdev->id) && | 4270 | (res->target == sdev->id) && |
3615 | (res->cfgte.res_addr.lun == sdev->lun)) | 4271 | (res->lun == sdev->lun)) |
3616 | return res; | 4272 | return res; |
3617 | } | 4273 | } |
3618 | 4274 | ||
@@ -3661,6 +4317,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) | |||
3661 | struct ipr_resource_entry *res; | 4317 | struct ipr_resource_entry *res; |
3662 | struct ata_port *ap = NULL; | 4318 | struct ata_port *ap = NULL; |
3663 | unsigned long lock_flags = 0; | 4319 | unsigned long lock_flags = 0; |
4320 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
3664 | 4321 | ||
3665 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 4322 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
3666 | res = sdev->hostdata; | 4323 | res = sdev->hostdata; |
@@ -3687,6 +4344,9 @@ static int ipr_slave_configure(struct scsi_device *sdev) | |||
3687 | ata_sas_slave_configure(sdev, ap); | 4344 | ata_sas_slave_configure(sdev, ap); |
3688 | } else | 4345 | } else |
3689 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); | 4346 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); |
4347 | if (ioa_cfg->sis64) | ||
4348 | sdev_printk(KERN_INFO, sdev, "Resource path: %s\n", | ||
4349 | ipr_format_resource_path(&res->res_path[0], &buffer[0])); | ||
3690 | return 0; | 4350 | return 0; |
3691 | } | 4351 | } |
3692 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4352 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
@@ -3828,14 +4488,19 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, | |||
3828 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | 4488 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); |
3829 | ioarcb = &ipr_cmd->ioarcb; | 4489 | ioarcb = &ipr_cmd->ioarcb; |
3830 | cmd_pkt = &ioarcb->cmd_pkt; | 4490 | cmd_pkt = &ioarcb->cmd_pkt; |
3831 | regs = &ioarcb->add_data.u.regs; | ||
3832 | 4491 | ||
3833 | ioarcb->res_handle = res->cfgte.res_handle; | 4492 | if (ipr_cmd->ioa_cfg->sis64) { |
4493 | regs = &ipr_cmd->i.ata_ioadl.regs; | ||
4494 | ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb)); | ||
4495 | } else | ||
4496 | regs = &ioarcb->u.add_data.u.regs; | ||
4497 | |||
4498 | ioarcb->res_handle = res->res_handle; | ||
3834 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; | 4499 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; |
3835 | cmd_pkt->cdb[0] = IPR_RESET_DEVICE; | 4500 | cmd_pkt->cdb[0] = IPR_RESET_DEVICE; |
3836 | if (ipr_is_gata(res)) { | 4501 | if (ipr_is_gata(res)) { |
3837 | cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET; | 4502 | cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET; |
3838 | ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags)); | 4503 | ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(regs->flags)); |
3839 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; | 4504 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; |
3840 | } | 4505 | } |
3841 | 4506 | ||
@@ -3880,19 +4545,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes, | |||
3880 | res = sata_port->res; | 4545 | res = sata_port->res; |
3881 | if (res) { | 4546 | if (res) { |
3882 | rc = ipr_device_reset(ioa_cfg, res); | 4547 | rc = ipr_device_reset(ioa_cfg, res); |
3883 | switch(res->cfgte.proto) { | 4548 | *classes = res->ata_class; |
3884 | case IPR_PROTO_SATA: | ||
3885 | case IPR_PROTO_SAS_STP: | ||
3886 | *classes = ATA_DEV_ATA; | ||
3887 | break; | ||
3888 | case IPR_PROTO_SATA_ATAPI: | ||
3889 | case IPR_PROTO_SAS_STP_ATAPI: | ||
3890 | *classes = ATA_DEV_ATAPI; | ||
3891 | break; | ||
3892 | default: | ||
3893 | *classes = ATA_DEV_UNKNOWN; | ||
3894 | break; | ||
3895 | }; | ||
3896 | } | 4549 | } |
3897 | 4550 | ||
3898 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4551 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
@@ -3937,7 +4590,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) | |||
3937 | return FAILED; | 4590 | return FAILED; |
3938 | 4591 | ||
3939 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { | 4592 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { |
3940 | if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { | 4593 | if (ipr_cmd->ioarcb.res_handle == res->res_handle) { |
3941 | if (ipr_cmd->scsi_cmd) | 4594 | if (ipr_cmd->scsi_cmd) |
3942 | ipr_cmd->done = ipr_scsi_eh_done; | 4595 | ipr_cmd->done = ipr_scsi_eh_done; |
3943 | if (ipr_cmd->qc) | 4596 | if (ipr_cmd->qc) |
@@ -3959,7 +4612,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) | |||
3959 | spin_lock_irq(scsi_cmd->device->host->host_lock); | 4612 | spin_lock_irq(scsi_cmd->device->host->host_lock); |
3960 | 4613 | ||
3961 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { | 4614 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { |
3962 | if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { | 4615 | if (ipr_cmd->ioarcb.res_handle == res->res_handle) { |
3963 | rc = -EIO; | 4616 | rc = -EIO; |
3964 | break; | 4617 | break; |
3965 | } | 4618 | } |
@@ -3998,13 +4651,13 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd) | |||
3998 | struct ipr_resource_entry *res; | 4651 | struct ipr_resource_entry *res; |
3999 | 4652 | ||
4000 | ENTER; | 4653 | ENTER; |
4001 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 4654 | if (!ioa_cfg->sis64) |
4002 | if (!memcmp(&res->cfgte.res_handle, &ipr_cmd->ioarcb.res_handle, | 4655 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
4003 | sizeof(res->cfgte.res_handle))) { | 4656 | if (res->res_handle == ipr_cmd->ioarcb.res_handle) { |
4004 | scsi_report_bus_reset(ioa_cfg->host, res->cfgte.res_addr.bus); | 4657 | scsi_report_bus_reset(ioa_cfg->host, res->bus); |
4005 | break; | 4658 | break; |
4659 | } | ||
4006 | } | 4660 | } |
4007 | } | ||
4008 | 4661 | ||
4009 | /* | 4662 | /* |
4010 | * If abort has not completed, indicate the reset has, else call the | 4663 | * If abort has not completed, indicate the reset has, else call the |
@@ -4102,7 +4755,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) | |||
4102 | return SUCCESS; | 4755 | return SUCCESS; |
4103 | 4756 | ||
4104 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | 4757 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); |
4105 | ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; | 4758 | ipr_cmd->ioarcb.res_handle = res->res_handle; |
4106 | cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; | 4759 | cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; |
4107 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; | 4760 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; |
4108 | cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; | 4761 | cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; |
@@ -4239,11 +4892,29 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4239 | return IRQ_NONE; | 4892 | return IRQ_NONE; |
4240 | } | 4893 | } |
4241 | 4894 | ||
4242 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 4895 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); |
4243 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | 4896 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; |
4244 | 4897 | ||
4245 | /* If an interrupt on the adapter did not occur, ignore it */ | 4898 | /* If an interrupt on the adapter did not occur, ignore it. |
4899 | * Or in the case of SIS 64, check for a stage change interrupt. | ||
4900 | */ | ||
4246 | if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { | 4901 | if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { |
4902 | if (ioa_cfg->sis64) { | ||
4903 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
4904 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | ||
4905 | if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { | ||
4906 | |||
4907 | /* clear stage change */ | ||
4908 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); | ||
4909 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | ||
4910 | list_del(&ioa_cfg->reset_cmd->queue); | ||
4911 | del_timer(&ioa_cfg->reset_cmd->timer); | ||
4912 | ipr_reset_ioa_job(ioa_cfg->reset_cmd); | ||
4913 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4914 | return IRQ_HANDLED; | ||
4915 | } | ||
4916 | } | ||
4917 | |||
4247 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4918 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
4248 | return IRQ_NONE; | 4919 | return IRQ_NONE; |
4249 | } | 4920 | } |
@@ -4286,8 +4957,8 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4286 | if (ipr_cmd != NULL) { | 4957 | if (ipr_cmd != NULL) { |
4287 | /* Clear the PCI interrupt */ | 4958 | /* Clear the PCI interrupt */ |
4288 | do { | 4959 | do { |
4289 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); | 4960 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); |
4290 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | 4961 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; |
4291 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && | 4962 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && |
4292 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); | 4963 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); |
4293 | 4964 | ||
@@ -4309,6 +4980,53 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4309 | } | 4980 | } |
4310 | 4981 | ||
4311 | /** | 4982 | /** |
4983 | * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer | ||
4984 | * @ioa_cfg: ioa config struct | ||
4985 | * @ipr_cmd: ipr command struct | ||
4986 | * | ||
4987 | * Return value: | ||
4988 | * 0 on success / -1 on failure | ||
4989 | **/ | ||
4990 | static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg, | ||
4991 | struct ipr_cmnd *ipr_cmd) | ||
4992 | { | ||
4993 | int i, nseg; | ||
4994 | struct scatterlist *sg; | ||
4995 | u32 length; | ||
4996 | u32 ioadl_flags = 0; | ||
4997 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | ||
4998 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | ||
4999 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
5000 | |||
5001 | length = scsi_bufflen(scsi_cmd); | ||
5002 | if (!length) | ||
5003 | return 0; | ||
5004 | |||
5005 | nseg = scsi_dma_map(scsi_cmd); | ||
5006 | if (nseg < 0) { | ||
5007 | dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n"); | ||
5008 | return -1; | ||
5009 | } | ||
5010 | |||
5011 | ipr_cmd->dma_use_sg = nseg; | ||
5012 | |||
5013 | if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { | ||
5014 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | ||
5015 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | ||
5016 | } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) | ||
5017 | ioadl_flags = IPR_IOADL_FLAGS_READ; | ||
5018 | |||
5019 | scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) { | ||
5020 | ioadl64[i].flags = cpu_to_be32(ioadl_flags); | ||
5021 | ioadl64[i].data_len = cpu_to_be32(sg_dma_len(sg)); | ||
5022 | ioadl64[i].address = cpu_to_be64(sg_dma_address(sg)); | ||
5023 | } | ||
5024 | |||
5025 | ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); | ||
5026 | return 0; | ||
5027 | } | ||
5028 | |||
5029 | /** | ||
4312 | * ipr_build_ioadl - Build a scatter/gather list and map the buffer | 5030 | * ipr_build_ioadl - Build a scatter/gather list and map the buffer |
4313 | * @ioa_cfg: ioa config struct | 5031 | * @ioa_cfg: ioa config struct |
4314 | * @ipr_cmd: ipr command struct | 5032 | * @ipr_cmd: ipr command struct |
@@ -4325,7 +5043,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, | |||
4325 | u32 ioadl_flags = 0; | 5043 | u32 ioadl_flags = 0; |
4326 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | 5044 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; |
4327 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 5045 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
4328 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | 5046 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; |
4329 | 5047 | ||
4330 | length = scsi_bufflen(scsi_cmd); | 5048 | length = scsi_bufflen(scsi_cmd); |
4331 | if (!length) | 5049 | if (!length) |
@@ -4342,8 +5060,8 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, | |||
4342 | if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { | 5060 | if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { |
4343 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | 5061 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; |
4344 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 5062 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
4345 | ioarcb->write_data_transfer_length = cpu_to_be32(length); | 5063 | ioarcb->data_transfer_length = cpu_to_be32(length); |
4346 | ioarcb->write_ioadl_len = | 5064 | ioarcb->ioadl_len = |
4347 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 5065 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
4348 | } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) { | 5066 | } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) { |
4349 | ioadl_flags = IPR_IOADL_FLAGS_READ; | 5067 | ioadl_flags = IPR_IOADL_FLAGS_READ; |
@@ -4352,11 +5070,10 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, | |||
4352 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 5070 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
4353 | } | 5071 | } |
4354 | 5072 | ||
4355 | if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) { | 5073 | if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->u.add_data.u.ioadl)) { |
4356 | ioadl = ioarcb->add_data.u.ioadl; | 5074 | ioadl = ioarcb->u.add_data.u.ioadl; |
4357 | ioarcb->write_ioadl_addr = | 5075 | ioarcb->write_ioadl_addr = cpu_to_be32((ipr_cmd->dma_addr) + |
4358 | cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + | 5076 | offsetof(struct ipr_ioarcb, u.add_data)); |
4359 | offsetof(struct ipr_ioarcb, add_data)); | ||
4360 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 5077 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; |
4361 | } | 5078 | } |
4362 | 5079 | ||
@@ -4446,18 +5163,24 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) | |||
4446 | { | 5163 | { |
4447 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 5164 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
4448 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 5165 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; |
4449 | dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); | 5166 | dma_addr_t dma_addr = ipr_cmd->dma_addr; |
4450 | 5167 | ||
4451 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); | 5168 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); |
4452 | ioarcb->write_data_transfer_length = 0; | 5169 | ioarcb->data_transfer_length = 0; |
4453 | ioarcb->read_data_transfer_length = 0; | 5170 | ioarcb->read_data_transfer_length = 0; |
4454 | ioarcb->write_ioadl_len = 0; | 5171 | ioarcb->ioadl_len = 0; |
4455 | ioarcb->read_ioadl_len = 0; | 5172 | ioarcb->read_ioadl_len = 0; |
4456 | ioasa->ioasc = 0; | 5173 | ioasa->ioasc = 0; |
4457 | ioasa->residual_data_len = 0; | 5174 | ioasa->residual_data_len = 0; |
4458 | ioarcb->write_ioadl_addr = | 5175 | |
4459 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); | 5176 | if (ipr_cmd->ioa_cfg->sis64) |
4460 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 5177 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
5178 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); | ||
5179 | else { | ||
5180 | ioarcb->write_ioadl_addr = | ||
5181 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | ||
5182 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | ||
5183 | } | ||
4461 | } | 5184 | } |
4462 | 5185 | ||
4463 | /** | 5186 | /** |
@@ -4489,15 +5212,8 @@ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) | |||
4489 | cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; | 5212 | cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; |
4490 | cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ); | 5213 | cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ); |
4491 | 5214 | ||
4492 | ipr_cmd->ioadl[0].flags_and_data_len = | 5215 | ipr_init_ioadl(ipr_cmd, ipr_cmd->sense_buffer_dma, |
4493 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | SCSI_SENSE_BUFFERSIZE); | 5216 | SCSI_SENSE_BUFFERSIZE, IPR_IOADL_FLAGS_READ_LAST); |
4494 | ipr_cmd->ioadl[0].address = | ||
4495 | cpu_to_be32(ipr_cmd->sense_buffer_dma); | ||
4496 | |||
4497 | ipr_cmd->ioarcb.read_ioadl_len = | ||
4498 | cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
4499 | ipr_cmd->ioarcb.read_data_transfer_length = | ||
4500 | cpu_to_be32(SCSI_SENSE_BUFFERSIZE); | ||
4501 | 5217 | ||
4502 | ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout, | 5218 | ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout, |
4503 | IPR_REQUEST_SENSE_TIMEOUT * 2); | 5219 | IPR_REQUEST_SENSE_TIMEOUT * 2); |
@@ -4893,9 +5609,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, | |||
4893 | 5609 | ||
4894 | memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len); | 5610 | memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len); |
4895 | ipr_cmd->scsi_cmd = scsi_cmd; | 5611 | ipr_cmd->scsi_cmd = scsi_cmd; |
4896 | ioarcb->res_handle = res->cfgte.res_handle; | 5612 | ioarcb->res_handle = res->res_handle; |
4897 | ipr_cmd->done = ipr_scsi_done; | 5613 | ipr_cmd->done = ipr_scsi_done; |
4898 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); | 5614 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res)); |
4899 | 5615 | ||
4900 | if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) { | 5616 | if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) { |
4901 | if (scsi_cmd->underflow == 0) | 5617 | if (scsi_cmd->underflow == 0) |
@@ -4916,13 +5632,16 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, | |||
4916 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) | 5632 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) |
4917 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 5633 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
4918 | 5634 | ||
4919 | if (likely(rc == 0)) | 5635 | if (likely(rc == 0)) { |
4920 | rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); | 5636 | if (ioa_cfg->sis64) |
5637 | rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); | ||
5638 | else | ||
5639 | rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); | ||
5640 | } | ||
4921 | 5641 | ||
4922 | if (likely(rc == 0)) { | 5642 | if (likely(rc == 0)) { |
4923 | mb(); | 5643 | mb(); |
4924 | writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), | 5644 | ipr_send_command(ipr_cmd); |
4925 | ioa_cfg->regs.ioarrin_reg); | ||
4926 | } else { | 5645 | } else { |
4927 | list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | 5646 | list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); |
4928 | return SCSI_MLQUEUE_HOST_BUSY; | 5647 | return SCSI_MLQUEUE_HOST_BUSY; |
@@ -5035,20 +5754,9 @@ static void ipr_ata_phy_reset(struct ata_port *ap) | |||
5035 | goto out_unlock; | 5754 | goto out_unlock; |
5036 | } | 5755 | } |
5037 | 5756 | ||
5038 | switch(res->cfgte.proto) { | 5757 | ap->link.device[0].class = res->ata_class; |
5039 | case IPR_PROTO_SATA: | 5758 | if (ap->link.device[0].class == ATA_DEV_UNKNOWN) |
5040 | case IPR_PROTO_SAS_STP: | ||
5041 | ap->link.device[0].class = ATA_DEV_ATA; | ||
5042 | break; | ||
5043 | case IPR_PROTO_SATA_ATAPI: | ||
5044 | case IPR_PROTO_SAS_STP_ATAPI: | ||
5045 | ap->link.device[0].class = ATA_DEV_ATAPI; | ||
5046 | break; | ||
5047 | default: | ||
5048 | ap->link.device[0].class = ATA_DEV_UNKNOWN; | ||
5049 | ata_port_disable(ap); | 5759 | ata_port_disable(ap); |
5050 | break; | ||
5051 | }; | ||
5052 | 5760 | ||
5053 | out_unlock: | 5761 | out_unlock: |
5054 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | 5762 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); |
@@ -5134,8 +5842,7 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) | |||
5134 | ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); | 5842 | ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); |
5135 | 5843 | ||
5136 | if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) | 5844 | if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) |
5137 | scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus, | 5845 | scsi_report_device_reset(ioa_cfg->host, res->bus, res->target); |
5138 | res->cfgte.res_addr.target); | ||
5139 | 5846 | ||
5140 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) | 5847 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) |
5141 | qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); | 5848 | qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); |
@@ -5146,6 +5853,52 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) | |||
5146 | } | 5853 | } |
5147 | 5854 | ||
5148 | /** | 5855 | /** |
5856 | * ipr_build_ata_ioadl64 - Build an ATA scatter/gather list | ||
5857 | * @ipr_cmd: ipr command struct | ||
5858 | * @qc: ATA queued command | ||
5859 | * | ||
5860 | **/ | ||
5861 | static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd, | ||
5862 | struct ata_queued_cmd *qc) | ||
5863 | { | ||
5864 | u32 ioadl_flags = 0; | ||
5865 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | ||
5866 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
5867 | struct ipr_ioadl64_desc *last_ioadl64 = NULL; | ||
5868 | int len = qc->nbytes; | ||
5869 | struct scatterlist *sg; | ||
5870 | unsigned int si; | ||
5871 | dma_addr_t dma_addr = ipr_cmd->dma_addr; | ||
5872 | |||
5873 | if (len == 0) | ||
5874 | return; | ||
5875 | |||
5876 | if (qc->dma_dir == DMA_TO_DEVICE) { | ||
5877 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | ||
5878 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | ||
5879 | } else if (qc->dma_dir == DMA_FROM_DEVICE) | ||
5880 | ioadl_flags = IPR_IOADL_FLAGS_READ; | ||
5881 | |||
5882 | ioarcb->data_transfer_length = cpu_to_be32(len); | ||
5883 | ioarcb->ioadl_len = | ||
5884 | cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); | ||
5885 | ioarcb->u.sis64_addr_data.data_ioadl_addr = | ||
5886 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl)); | ||
5887 | |||
5888 | for_each_sg(qc->sg, sg, qc->n_elem, si) { | ||
5889 | ioadl64->flags = cpu_to_be32(ioadl_flags); | ||
5890 | ioadl64->data_len = cpu_to_be32(sg_dma_len(sg)); | ||
5891 | ioadl64->address = cpu_to_be64(sg_dma_address(sg)); | ||
5892 | |||
5893 | last_ioadl64 = ioadl64; | ||
5894 | ioadl64++; | ||
5895 | } | ||
5896 | |||
5897 | if (likely(last_ioadl64)) | ||
5898 | last_ioadl64->flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); | ||
5899 | } | ||
5900 | |||
5901 | /** | ||
5149 | * ipr_build_ata_ioadl - Build an ATA scatter/gather list | 5902 | * ipr_build_ata_ioadl - Build an ATA scatter/gather list |
5150 | * @ipr_cmd: ipr command struct | 5903 | * @ipr_cmd: ipr command struct |
5151 | * @qc: ATA queued command | 5904 | * @qc: ATA queued command |
@@ -5156,7 +5909,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, | |||
5156 | { | 5909 | { |
5157 | u32 ioadl_flags = 0; | 5910 | u32 ioadl_flags = 0; |
5158 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 5911 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5159 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | 5912 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; |
5160 | struct ipr_ioadl_desc *last_ioadl = NULL; | 5913 | struct ipr_ioadl_desc *last_ioadl = NULL; |
5161 | int len = qc->nbytes; | 5914 | int len = qc->nbytes; |
5162 | struct scatterlist *sg; | 5915 | struct scatterlist *sg; |
@@ -5168,8 +5921,8 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, | |||
5168 | if (qc->dma_dir == DMA_TO_DEVICE) { | 5921 | if (qc->dma_dir == DMA_TO_DEVICE) { |
5169 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | 5922 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; |
5170 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 5923 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
5171 | ioarcb->write_data_transfer_length = cpu_to_be32(len); | 5924 | ioarcb->data_transfer_length = cpu_to_be32(len); |
5172 | ioarcb->write_ioadl_len = | 5925 | ioarcb->ioadl_len = |
5173 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 5926 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
5174 | } else if (qc->dma_dir == DMA_FROM_DEVICE) { | 5927 | } else if (qc->dma_dir == DMA_FROM_DEVICE) { |
5175 | ioadl_flags = IPR_IOADL_FLAGS_READ; | 5928 | ioadl_flags = IPR_IOADL_FLAGS_READ; |
@@ -5212,25 +5965,34 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) | |||
5212 | 5965 | ||
5213 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | 5966 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); |
5214 | ioarcb = &ipr_cmd->ioarcb; | 5967 | ioarcb = &ipr_cmd->ioarcb; |
5215 | regs = &ioarcb->add_data.u.regs; | ||
5216 | 5968 | ||
5217 | memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data)); | 5969 | if (ioa_cfg->sis64) { |
5218 | ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs)); | 5970 | regs = &ipr_cmd->i.ata_ioadl.regs; |
5971 | ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb)); | ||
5972 | } else | ||
5973 | regs = &ioarcb->u.add_data.u.regs; | ||
5974 | |||
5975 | memset(regs, 0, sizeof(*regs)); | ||
5976 | ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs)); | ||
5219 | 5977 | ||
5220 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); | 5978 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); |
5221 | ipr_cmd->qc = qc; | 5979 | ipr_cmd->qc = qc; |
5222 | ipr_cmd->done = ipr_sata_done; | 5980 | ipr_cmd->done = ipr_sata_done; |
5223 | ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; | 5981 | ipr_cmd->ioarcb.res_handle = res->res_handle; |
5224 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; | 5982 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; |
5225 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; | 5983 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; |
5226 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; | 5984 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; |
5227 | ipr_cmd->dma_use_sg = qc->n_elem; | 5985 | ipr_cmd->dma_use_sg = qc->n_elem; |
5228 | 5986 | ||
5229 | ipr_build_ata_ioadl(ipr_cmd, qc); | 5987 | if (ioa_cfg->sis64) |
5988 | ipr_build_ata_ioadl64(ipr_cmd, qc); | ||
5989 | else | ||
5990 | ipr_build_ata_ioadl(ipr_cmd, qc); | ||
5991 | |||
5230 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; | 5992 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; |
5231 | ipr_copy_sata_tf(regs, &qc->tf); | 5993 | ipr_copy_sata_tf(regs, &qc->tf); |
5232 | memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); | 5994 | memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); |
5233 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); | 5995 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res)); |
5234 | 5996 | ||
5235 | switch (qc->tf.protocol) { | 5997 | switch (qc->tf.protocol) { |
5236 | case ATA_PROT_NODATA: | 5998 | case ATA_PROT_NODATA: |
@@ -5257,8 +6019,9 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) | |||
5257 | } | 6019 | } |
5258 | 6020 | ||
5259 | mb(); | 6021 | mb(); |
5260 | writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr), | 6022 | |
5261 | ioa_cfg->regs.ioarrin_reg); | 6023 | ipr_send_command(ipr_cmd); |
6024 | |||
5262 | return 0; | 6025 | return 0; |
5263 | } | 6026 | } |
5264 | 6027 | ||
@@ -5459,7 +6222,7 @@ static void ipr_set_sup_dev_dflt(struct ipr_supported_device *supported_dev, | |||
5459 | * ipr_set_supported_devs - Send Set Supported Devices for a device | 6222 | * ipr_set_supported_devs - Send Set Supported Devices for a device |
5460 | * @ipr_cmd: ipr command struct | 6223 | * @ipr_cmd: ipr command struct |
5461 | * | 6224 | * |
5462 | * This function send a Set Supported Devices to the adapter | 6225 | * This function sends a Set Supported Devices to the adapter |
5463 | * | 6226 | * |
5464 | * Return value: | 6227 | * Return value: |
5465 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | 6228 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN |
@@ -5468,7 +6231,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) | |||
5468 | { | 6231 | { |
5469 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6232 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
5470 | struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev; | 6233 | struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev; |
5471 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
5472 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6234 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5473 | struct ipr_resource_entry *res = ipr_cmd->u.res; | 6235 | struct ipr_resource_entry *res = ipr_cmd->u.res; |
5474 | 6236 | ||
@@ -5479,28 +6241,28 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) | |||
5479 | continue; | 6241 | continue; |
5480 | 6242 | ||
5481 | ipr_cmd->u.res = res; | 6243 | ipr_cmd->u.res = res; |
5482 | ipr_set_sup_dev_dflt(supp_dev, &res->cfgte.std_inq_data.vpids); | 6244 | ipr_set_sup_dev_dflt(supp_dev, &res->std_inq_data.vpids); |
5483 | 6245 | ||
5484 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 6246 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
5485 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 6247 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
5486 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 6248 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
5487 | 6249 | ||
5488 | ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES; | 6250 | ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES; |
6251 | ioarcb->cmd_pkt.cdb[1] = IPR_SET_ALL_SUPPORTED_DEVICES; | ||
5489 | ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff; | 6252 | ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff; |
5490 | ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff; | 6253 | ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff; |
5491 | 6254 | ||
5492 | ioadl->flags_and_data_len = cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | | 6255 | ipr_init_ioadl(ipr_cmd, |
5493 | sizeof(struct ipr_supported_device)); | 6256 | ioa_cfg->vpd_cbs_dma + |
5494 | ioadl->address = cpu_to_be32(ioa_cfg->vpd_cbs_dma + | 6257 | offsetof(struct ipr_misc_cbs, supp_dev), |
5495 | offsetof(struct ipr_misc_cbs, supp_dev)); | 6258 | sizeof(struct ipr_supported_device), |
5496 | ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 6259 | IPR_IOADL_FLAGS_WRITE_LAST); |
5497 | ioarcb->write_data_transfer_length = | ||
5498 | cpu_to_be32(sizeof(struct ipr_supported_device)); | ||
5499 | 6260 | ||
5500 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, | 6261 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, |
5501 | IPR_SET_SUP_DEVICE_TIMEOUT); | 6262 | IPR_SET_SUP_DEVICE_TIMEOUT); |
5502 | 6263 | ||
5503 | ipr_cmd->job_step = ipr_set_supported_devs; | 6264 | if (!ioa_cfg->sis64) |
6265 | ipr_cmd->job_step = ipr_set_supported_devs; | ||
5504 | return IPR_RC_JOB_RETURN; | 6266 | return IPR_RC_JOB_RETURN; |
5505 | } | 6267 | } |
5506 | 6268 | ||
@@ -5508,36 +6270,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) | |||
5508 | } | 6270 | } |
5509 | 6271 | ||
5510 | /** | 6272 | /** |
5511 | * ipr_setup_write_cache - Disable write cache if needed | ||
5512 | * @ipr_cmd: ipr command struct | ||
5513 | * | ||
5514 | * This function sets up adapters write cache to desired setting | ||
5515 | * | ||
5516 | * Return value: | ||
5517 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | ||
5518 | **/ | ||
5519 | static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd) | ||
5520 | { | ||
5521 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
5522 | |||
5523 | ipr_cmd->job_step = ipr_set_supported_devs; | ||
5524 | ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, | ||
5525 | struct ipr_resource_entry, queue); | ||
5526 | |||
5527 | if (ioa_cfg->cache_state != CACHE_DISABLED) | ||
5528 | return IPR_RC_JOB_CONTINUE; | ||
5529 | |||
5530 | ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | ||
5531 | ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | ||
5532 | ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; | ||
5533 | ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; | ||
5534 | |||
5535 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | ||
5536 | |||
5537 | return IPR_RC_JOB_RETURN; | ||
5538 | } | ||
5539 | |||
5540 | /** | ||
5541 | * ipr_get_mode_page - Locate specified mode page | 6273 | * ipr_get_mode_page - Locate specified mode page |
5542 | * @mode_pages: mode page buffer | 6274 | * @mode_pages: mode page buffer |
5543 | * @page_code: page code to find | 6275 | * @page_code: page code to find |
@@ -5695,10 +6427,9 @@ static void ipr_modify_ioafp_mode_page_28(struct ipr_ioa_cfg *ioa_cfg, | |||
5695 | * none | 6427 | * none |
5696 | **/ | 6428 | **/ |
5697 | static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, | 6429 | static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, |
5698 | __be32 res_handle, u8 parm, u32 dma_addr, | 6430 | __be32 res_handle, u8 parm, |
5699 | u8 xfer_len) | 6431 | dma_addr_t dma_addr, u8 xfer_len) |
5700 | { | 6432 | { |
5701 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
5702 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6433 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5703 | 6434 | ||
5704 | ioarcb->res_handle = res_handle; | 6435 | ioarcb->res_handle = res_handle; |
@@ -5708,11 +6439,7 @@ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, | |||
5708 | ioarcb->cmd_pkt.cdb[1] = parm; | 6439 | ioarcb->cmd_pkt.cdb[1] = parm; |
5709 | ioarcb->cmd_pkt.cdb[4] = xfer_len; | 6440 | ioarcb->cmd_pkt.cdb[4] = xfer_len; |
5710 | 6441 | ||
5711 | ioadl->flags_and_data_len = | 6442 | ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_WRITE_LAST); |
5712 | cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | xfer_len); | ||
5713 | ioadl->address = cpu_to_be32(dma_addr); | ||
5714 | ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
5715 | ioarcb->write_data_transfer_length = cpu_to_be32(xfer_len); | ||
5716 | } | 6443 | } |
5717 | 6444 | ||
5718 | /** | 6445 | /** |
@@ -5742,7 +6469,9 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) | |||
5742 | ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), | 6469 | ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), |
5743 | length); | 6470 | length); |
5744 | 6471 | ||
5745 | ipr_cmd->job_step = ipr_setup_write_cache; | 6472 | ipr_cmd->job_step = ipr_set_supported_devs; |
6473 | ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, | ||
6474 | struct ipr_resource_entry, queue); | ||
5746 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | 6475 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); |
5747 | 6476 | ||
5748 | LEAVE; | 6477 | LEAVE; |
@@ -5762,9 +6491,8 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) | |||
5762 | **/ | 6491 | **/ |
5763 | static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, | 6492 | static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, |
5764 | __be32 res_handle, | 6493 | __be32 res_handle, |
5765 | u8 parm, u32 dma_addr, u8 xfer_len) | 6494 | u8 parm, dma_addr_t dma_addr, u8 xfer_len) |
5766 | { | 6495 | { |
5767 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
5768 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6496 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5769 | 6497 | ||
5770 | ioarcb->res_handle = res_handle; | 6498 | ioarcb->res_handle = res_handle; |
@@ -5773,11 +6501,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, | |||
5773 | ioarcb->cmd_pkt.cdb[4] = xfer_len; | 6501 | ioarcb->cmd_pkt.cdb[4] = xfer_len; |
5774 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; | 6502 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; |
5775 | 6503 | ||
5776 | ioadl->flags_and_data_len = | 6504 | ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST); |
5777 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len); | ||
5778 | ioadl->address = cpu_to_be32(dma_addr); | ||
5779 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
5780 | ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len); | ||
5781 | } | 6505 | } |
5782 | 6506 | ||
5783 | /** | 6507 | /** |
@@ -5815,10 +6539,13 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) | |||
5815 | **/ | 6539 | **/ |
5816 | static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) | 6540 | static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) |
5817 | { | 6541 | { |
6542 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
5818 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 6543 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); |
5819 | 6544 | ||
5820 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { | 6545 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { |
5821 | ipr_cmd->job_step = ipr_setup_write_cache; | 6546 | ipr_cmd->job_step = ipr_set_supported_devs; |
6547 | ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, | ||
6548 | struct ipr_resource_entry, queue); | ||
5822 | return IPR_RC_JOB_CONTINUE; | 6549 | return IPR_RC_JOB_CONTINUE; |
5823 | } | 6550 | } |
5824 | 6551 | ||
@@ -5958,24 +6685,36 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) | |||
5958 | { | 6685 | { |
5959 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6686 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
5960 | struct ipr_resource_entry *res, *temp; | 6687 | struct ipr_resource_entry *res, *temp; |
5961 | struct ipr_config_table_entry *cfgte; | 6688 | struct ipr_config_table_entry_wrapper cfgtew; |
5962 | int found, i; | 6689 | int entries, found, flag, i; |
5963 | LIST_HEAD(old_res); | 6690 | LIST_HEAD(old_res); |
5964 | 6691 | ||
5965 | ENTER; | 6692 | ENTER; |
5966 | if (ioa_cfg->cfg_table->hdr.flags & IPR_UCODE_DOWNLOAD_REQ) | 6693 | if (ioa_cfg->sis64) |
6694 | flag = ioa_cfg->u.cfg_table64->hdr64.flags; | ||
6695 | else | ||
6696 | flag = ioa_cfg->u.cfg_table->hdr.flags; | ||
6697 | |||
6698 | if (flag & IPR_UCODE_DOWNLOAD_REQ) | ||
5967 | dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n"); | 6699 | dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n"); |
5968 | 6700 | ||
5969 | list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue) | 6701 | list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue) |
5970 | list_move_tail(&res->queue, &old_res); | 6702 | list_move_tail(&res->queue, &old_res); |
5971 | 6703 | ||
5972 | for (i = 0; i < ioa_cfg->cfg_table->hdr.num_entries; i++) { | 6704 | if (ioa_cfg->sis64) |
5973 | cfgte = &ioa_cfg->cfg_table->dev[i]; | 6705 | entries = ioa_cfg->u.cfg_table64->hdr64.num_entries; |
6706 | else | ||
6707 | entries = ioa_cfg->u.cfg_table->hdr.num_entries; | ||
6708 | |||
6709 | for (i = 0; i < entries; i++) { | ||
6710 | if (ioa_cfg->sis64) | ||
6711 | cfgtew.u.cfgte64 = &ioa_cfg->u.cfg_table64->dev[i]; | ||
6712 | else | ||
6713 | cfgtew.u.cfgte = &ioa_cfg->u.cfg_table->dev[i]; | ||
5974 | found = 0; | 6714 | found = 0; |
5975 | 6715 | ||
5976 | list_for_each_entry_safe(res, temp, &old_res, queue) { | 6716 | list_for_each_entry_safe(res, temp, &old_res, queue) { |
5977 | if (!memcmp(&res->cfgte.res_addr, | 6717 | if (ipr_is_same_device(res, &cfgtew)) { |
5978 | &cfgte->res_addr, sizeof(cfgte->res_addr))) { | ||
5979 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); | 6718 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); |
5980 | found = 1; | 6719 | found = 1; |
5981 | break; | 6720 | break; |
@@ -5992,24 +6731,27 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) | |||
5992 | res = list_entry(ioa_cfg->free_res_q.next, | 6731 | res = list_entry(ioa_cfg->free_res_q.next, |
5993 | struct ipr_resource_entry, queue); | 6732 | struct ipr_resource_entry, queue); |
5994 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); | 6733 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); |
5995 | ipr_init_res_entry(res); | 6734 | ipr_init_res_entry(res, &cfgtew); |
5996 | res->add_to_ml = 1; | 6735 | res->add_to_ml = 1; |
5997 | } | 6736 | } |
5998 | 6737 | ||
5999 | if (found) | 6738 | if (found) |
6000 | memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); | 6739 | ipr_update_res_entry(res, &cfgtew); |
6001 | } | 6740 | } |
6002 | 6741 | ||
6003 | list_for_each_entry_safe(res, temp, &old_res, queue) { | 6742 | list_for_each_entry_safe(res, temp, &old_res, queue) { |
6004 | if (res->sdev) { | 6743 | if (res->sdev) { |
6005 | res->del_from_ml = 1; | 6744 | res->del_from_ml = 1; |
6006 | res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; | 6745 | res->res_handle = IPR_INVALID_RES_HANDLE; |
6007 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); | 6746 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); |
6008 | } else { | ||
6009 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); | ||
6010 | } | 6747 | } |
6011 | } | 6748 | } |
6012 | 6749 | ||
6750 | list_for_each_entry_safe(res, temp, &old_res, queue) { | ||
6751 | ipr_clear_res_target(res); | ||
6752 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); | ||
6753 | } | ||
6754 | |||
6013 | if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) | 6755 | if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) |
6014 | ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; | 6756 | ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; |
6015 | else | 6757 | else |
@@ -6033,7 +6775,6 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) | |||
6033 | { | 6775 | { |
6034 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6776 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
6035 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6777 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
6036 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
6037 | struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; | 6778 | struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; |
6038 | struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; | 6779 | struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; |
6039 | 6780 | ||
@@ -6047,16 +6788,11 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) | |||
6047 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 6788 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
6048 | 6789 | ||
6049 | ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; | 6790 | ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; |
6050 | ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff; | 6791 | ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff; |
6051 | ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff; | 6792 | ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff; |
6052 | 6793 | ||
6053 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 6794 | ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, ioa_cfg->cfg_table_size, |
6054 | ioarcb->read_data_transfer_length = | 6795 | IPR_IOADL_FLAGS_READ_LAST); |
6055 | cpu_to_be32(sizeof(struct ipr_config_table)); | ||
6056 | |||
6057 | ioadl->address = cpu_to_be32(ioa_cfg->cfg_table_dma); | ||
6058 | ioadl->flags_and_data_len = | ||
6059 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(struct ipr_config_table)); | ||
6060 | 6796 | ||
6061 | ipr_cmd->job_step = ipr_init_res_table; | 6797 | ipr_cmd->job_step = ipr_init_res_table; |
6062 | 6798 | ||
@@ -6076,10 +6812,9 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) | |||
6076 | * none | 6812 | * none |
6077 | **/ | 6813 | **/ |
6078 | static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, | 6814 | static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, |
6079 | u32 dma_addr, u8 xfer_len) | 6815 | dma_addr_t dma_addr, u8 xfer_len) |
6080 | { | 6816 | { |
6081 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6817 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
6082 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
6083 | 6818 | ||
6084 | ENTER; | 6819 | ENTER; |
6085 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; | 6820 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; |
@@ -6090,12 +6825,7 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, | |||
6090 | ioarcb->cmd_pkt.cdb[2] = page; | 6825 | ioarcb->cmd_pkt.cdb[2] = page; |
6091 | ioarcb->cmd_pkt.cdb[4] = xfer_len; | 6826 | ioarcb->cmd_pkt.cdb[4] = xfer_len; |
6092 | 6827 | ||
6093 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 6828 | ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST); |
6094 | ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len); | ||
6095 | |||
6096 | ioadl->address = cpu_to_be32(dma_addr); | ||
6097 | ioadl->flags_and_data_len = | ||
6098 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len); | ||
6099 | 6829 | ||
6100 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | 6830 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); |
6101 | LEAVE; | 6831 | LEAVE; |
@@ -6166,13 +6896,9 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6166 | static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) | 6896 | static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) |
6167 | { | 6897 | { |
6168 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6898 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
6169 | struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data; | ||
6170 | 6899 | ||
6171 | ENTER; | 6900 | ENTER; |
6172 | 6901 | ||
6173 | if (!ipr_inquiry_page_supported(page0, 1)) | ||
6174 | ioa_cfg->cache_state = CACHE_NONE; | ||
6175 | |||
6176 | ipr_cmd->job_step = ipr_ioafp_cap_inquiry; | 6902 | ipr_cmd->job_step = ipr_ioafp_cap_inquiry; |
6177 | 6903 | ||
6178 | ipr_ioafp_inquiry(ipr_cmd, 1, 3, | 6904 | ipr_ioafp_inquiry(ipr_cmd, 1, 3, |
@@ -6240,7 +6966,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6240 | } | 6966 | } |
6241 | 6967 | ||
6242 | /** | 6968 | /** |
6243 | * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ. | 6969 | * ipr_ioafp_identify_hrrq - Send Identify Host RRQ. |
6244 | * @ipr_cmd: ipr command struct | 6970 | * @ipr_cmd: ipr command struct |
6245 | * | 6971 | * |
6246 | * This function send an Identify Host Request Response Queue | 6972 | * This function send an Identify Host Request Response Queue |
@@ -6249,7 +6975,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6249 | * Return value: | 6975 | * Return value: |
6250 | * IPR_RC_JOB_RETURN | 6976 | * IPR_RC_JOB_RETURN |
6251 | **/ | 6977 | **/ |
6252 | static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) | 6978 | static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd) |
6253 | { | 6979 | { |
6254 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6980 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
6255 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6981 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
@@ -6261,19 +6987,32 @@ static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) | |||
6261 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 6987 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
6262 | 6988 | ||
6263 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 6989 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
6990 | if (ioa_cfg->sis64) | ||
6991 | ioarcb->cmd_pkt.cdb[1] = 0x1; | ||
6264 | ioarcb->cmd_pkt.cdb[2] = | 6992 | ioarcb->cmd_pkt.cdb[2] = |
6265 | ((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff; | 6993 | ((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff; |
6266 | ioarcb->cmd_pkt.cdb[3] = | 6994 | ioarcb->cmd_pkt.cdb[3] = |
6267 | ((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff; | 6995 | ((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff; |
6268 | ioarcb->cmd_pkt.cdb[4] = | 6996 | ioarcb->cmd_pkt.cdb[4] = |
6269 | ((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff; | 6997 | ((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff; |
6270 | ioarcb->cmd_pkt.cdb[5] = | 6998 | ioarcb->cmd_pkt.cdb[5] = |
6271 | ((u32) ioa_cfg->host_rrq_dma) & 0xff; | 6999 | ((u64) ioa_cfg->host_rrq_dma) & 0xff; |
6272 | ioarcb->cmd_pkt.cdb[7] = | 7000 | ioarcb->cmd_pkt.cdb[7] = |
6273 | ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; | 7001 | ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; |
6274 | ioarcb->cmd_pkt.cdb[8] = | 7002 | ioarcb->cmd_pkt.cdb[8] = |
6275 | (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; | 7003 | (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; |
6276 | 7004 | ||
7005 | if (ioa_cfg->sis64) { | ||
7006 | ioarcb->cmd_pkt.cdb[10] = | ||
7007 | ((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff; | ||
7008 | ioarcb->cmd_pkt.cdb[11] = | ||
7009 | ((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff; | ||
7010 | ioarcb->cmd_pkt.cdb[12] = | ||
7011 | ((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff; | ||
7012 | ioarcb->cmd_pkt.cdb[13] = | ||
7013 | ((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff; | ||
7014 | } | ||
7015 | |||
6277 | ipr_cmd->job_step = ipr_ioafp_std_inquiry; | 7016 | ipr_cmd->job_step = ipr_ioafp_std_inquiry; |
6278 | 7017 | ||
6279 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | 7018 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); |
@@ -6354,7 +7093,58 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
6354 | ioa_cfg->toggle_bit = 1; | 7093 | ioa_cfg->toggle_bit = 1; |
6355 | 7094 | ||
6356 | /* Zero out config table */ | 7095 | /* Zero out config table */ |
6357 | memset(ioa_cfg->cfg_table, 0, sizeof(struct ipr_config_table)); | 7096 | memset(ioa_cfg->u.cfg_table, 0, ioa_cfg->cfg_table_size); |
7097 | } | ||
7098 | |||
7099 | /** | ||
7100 | * ipr_reset_next_stage - Process IPL stage change based on feedback register. | ||
7101 | * @ipr_cmd: ipr command struct | ||
7102 | * | ||
7103 | * Return value: | ||
7104 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | ||
7105 | **/ | ||
7106 | static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd) | ||
7107 | { | ||
7108 | unsigned long stage, stage_time; | ||
7109 | u32 feedback; | ||
7110 | volatile u32 int_reg; | ||
7111 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
7112 | u64 maskval = 0; | ||
7113 | |||
7114 | feedback = readl(ioa_cfg->regs.init_feedback_reg); | ||
7115 | stage = feedback & IPR_IPL_INIT_STAGE_MASK; | ||
7116 | stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK; | ||
7117 | |||
7118 | ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time); | ||
7119 | |||
7120 | /* sanity check the stage_time value */ | ||
7121 | if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) | ||
7122 | stage_time = IPR_IPL_INIT_MIN_STAGE_TIME; | ||
7123 | else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT) | ||
7124 | stage_time = IPR_LONG_OPERATIONAL_TIMEOUT; | ||
7125 | |||
7126 | if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) { | ||
7127 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg); | ||
7128 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
7129 | stage_time = ioa_cfg->transop_timeout; | ||
7130 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; | ||
7131 | } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) { | ||
7132 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; | ||
7133 | maskval = IPR_PCII_IPL_STAGE_CHANGE; | ||
7134 | maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER; | ||
7135 | writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg); | ||
7136 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
7137 | return IPR_RC_JOB_CONTINUE; | ||
7138 | } | ||
7139 | |||
7140 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; | ||
7141 | ipr_cmd->timer.expires = jiffies + stage_time * HZ; | ||
7142 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; | ||
7143 | ipr_cmd->done = ipr_reset_ioa_job; | ||
7144 | add_timer(&ipr_cmd->timer); | ||
7145 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); | ||
7146 | |||
7147 | return IPR_RC_JOB_RETURN; | ||
6358 | } | 7148 | } |
6359 | 7149 | ||
6360 | /** | 7150 | /** |
@@ -6373,7 +7163,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) | |||
6373 | volatile u32 int_reg; | 7163 | volatile u32 int_reg; |
6374 | 7164 | ||
6375 | ENTER; | 7165 | ENTER; |
6376 | ipr_cmd->job_step = ipr_ioafp_indentify_hrrq; | 7166 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; |
6377 | ipr_init_ioa_mem(ioa_cfg); | 7167 | ipr_init_ioa_mem(ioa_cfg); |
6378 | 7168 | ||
6379 | ioa_cfg->allow_interrupts = 1; | 7169 | ioa_cfg->allow_interrupts = 1; |
@@ -6381,19 +7171,27 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) | |||
6381 | 7171 | ||
6382 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { | 7172 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { |
6383 | writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), | 7173 | writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), |
6384 | ioa_cfg->regs.clr_interrupt_mask_reg); | 7174 | ioa_cfg->regs.clr_interrupt_mask_reg32); |
6385 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 7175 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
6386 | return IPR_RC_JOB_CONTINUE; | 7176 | return IPR_RC_JOB_CONTINUE; |
6387 | } | 7177 | } |
6388 | 7178 | ||
6389 | /* Enable destructive diagnostics on IOA */ | 7179 | /* Enable destructive diagnostics on IOA */ |
6390 | writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg); | 7180 | writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32); |
7181 | |||
7182 | writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); | ||
7183 | if (ioa_cfg->sis64) | ||
7184 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg); | ||
6391 | 7185 | ||
6392 | writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg); | ||
6393 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 7186 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
6394 | 7187 | ||
6395 | dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); | 7188 | dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); |
6396 | 7189 | ||
7190 | if (ioa_cfg->sis64) { | ||
7191 | ipr_cmd->job_step = ipr_reset_next_stage; | ||
7192 | return IPR_RC_JOB_CONTINUE; | ||
7193 | } | ||
7194 | |||
6397 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; | 7195 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; |
6398 | ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); | 7196 | ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); |
6399 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; | 7197 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; |
@@ -6463,7 +7261,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) | |||
6463 | 7261 | ||
6464 | mailbox = readl(ioa_cfg->ioa_mailbox); | 7262 | mailbox = readl(ioa_cfg->ioa_mailbox); |
6465 | 7263 | ||
6466 | if (!ipr_sdt_is_fmt2(mailbox)) { | 7264 | if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) { |
6467 | ipr_unit_check_no_data(ioa_cfg); | 7265 | ipr_unit_check_no_data(ioa_cfg); |
6468 | return; | 7266 | return; |
6469 | } | 7267 | } |
@@ -6472,15 +7270,20 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) | |||
6472 | rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt, | 7270 | rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt, |
6473 | (sizeof(struct ipr_uc_sdt)) / sizeof(__be32)); | 7271 | (sizeof(struct ipr_uc_sdt)) / sizeof(__be32)); |
6474 | 7272 | ||
6475 | if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) || | 7273 | if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) || |
6476 | !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) { | 7274 | ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) && |
7275 | (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) { | ||
6477 | ipr_unit_check_no_data(ioa_cfg); | 7276 | ipr_unit_check_no_data(ioa_cfg); |
6478 | return; | 7277 | return; |
6479 | } | 7278 | } |
6480 | 7279 | ||
6481 | /* Find length of the first sdt entry (UC buffer) */ | 7280 | /* Find length of the first sdt entry (UC buffer) */ |
6482 | length = (be32_to_cpu(sdt.entry[0].end_offset) - | 7281 | if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE) |
6483 | be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK; | 7282 | length = be32_to_cpu(sdt.entry[0].end_token); |
7283 | else | ||
7284 | length = (be32_to_cpu(sdt.entry[0].end_token) - | ||
7285 | be32_to_cpu(sdt.entry[0].start_token)) & | ||
7286 | IPR_FMT2_MBX_ADDR_MASK; | ||
6484 | 7287 | ||
6485 | hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next, | 7288 | hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next, |
6486 | struct ipr_hostrcb, queue); | 7289 | struct ipr_hostrcb, queue); |
@@ -6488,13 +7291,13 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) | |||
6488 | memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam)); | 7291 | memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam)); |
6489 | 7292 | ||
6490 | rc = ipr_get_ldump_data_section(ioa_cfg, | 7293 | rc = ipr_get_ldump_data_section(ioa_cfg, |
6491 | be32_to_cpu(sdt.entry[0].bar_str_offset), | 7294 | be32_to_cpu(sdt.entry[0].start_token), |
6492 | (__be32 *)&hostrcb->hcam, | 7295 | (__be32 *)&hostrcb->hcam, |
6493 | min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32)); | 7296 | min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32)); |
6494 | 7297 | ||
6495 | if (!rc) { | 7298 | if (!rc) { |
6496 | ipr_handle_log_data(ioa_cfg, hostrcb); | 7299 | ipr_handle_log_data(ioa_cfg, hostrcb); |
6497 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); | 7300 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); |
6498 | if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && | 7301 | if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && |
6499 | ioa_cfg->sdt_state == GET_DUMP) | 7302 | ioa_cfg->sdt_state == GET_DUMP) |
6500 | ioa_cfg->sdt_state = WAIT_FOR_DUMP; | 7303 | ioa_cfg->sdt_state = WAIT_FOR_DUMP; |
@@ -6722,7 +7525,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd) | |||
6722 | 7525 | ||
6723 | if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { | 7526 | if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { |
6724 | ipr_mask_and_clear_interrupts(ioa_cfg, ~0); | 7527 | ipr_mask_and_clear_interrupts(ioa_cfg, ~0); |
6725 | writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg); | 7528 | writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32); |
6726 | ipr_cmd->job_step = ipr_reset_wait_to_start_bist; | 7529 | ipr_cmd->job_step = ipr_reset_wait_to_start_bist; |
6727 | } else { | 7530 | } else { |
6728 | ipr_cmd->job_step = ioa_cfg->reset; | 7531 | ipr_cmd->job_step = ioa_cfg->reset; |
@@ -6785,7 +7588,10 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd) | |||
6785 | ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8; | 7588 | ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8; |
6786 | ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff; | 7589 | ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff; |
6787 | 7590 | ||
6788 | ipr_build_ucode_ioadl(ipr_cmd, sglist); | 7591 | if (ioa_cfg->sis64) |
7592 | ipr_build_ucode_ioadl64(ipr_cmd, sglist); | ||
7593 | else | ||
7594 | ipr_build_ucode_ioadl(ipr_cmd, sglist); | ||
6789 | ipr_cmd->job_step = ipr_reset_ucode_download_done; | 7595 | ipr_cmd->job_step = ipr_reset_ucode_download_done; |
6790 | 7596 | ||
6791 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, | 7597 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, |
@@ -7154,8 +7960,8 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
7154 | ipr_free_cmd_blks(ioa_cfg); | 7960 | ipr_free_cmd_blks(ioa_cfg); |
7155 | pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, | 7961 | pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, |
7156 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); | 7962 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); |
7157 | pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_config_table), | 7963 | pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size, |
7158 | ioa_cfg->cfg_table, | 7964 | ioa_cfg->u.cfg_table, |
7159 | ioa_cfg->cfg_table_dma); | 7965 | ioa_cfg->cfg_table_dma); |
7160 | 7966 | ||
7161 | for (i = 0; i < IPR_NUM_HCAMS; i++) { | 7967 | for (i = 0; i < IPR_NUM_HCAMS; i++) { |
@@ -7209,7 +8015,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) | |||
7209 | int i; | 8015 | int i; |
7210 | 8016 | ||
7211 | ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, | 8017 | ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, |
7212 | sizeof(struct ipr_cmnd), 8, 0); | 8018 | sizeof(struct ipr_cmnd), 16, 0); |
7213 | 8019 | ||
7214 | if (!ioa_cfg->ipr_cmd_pool) | 8020 | if (!ioa_cfg->ipr_cmd_pool) |
7215 | return -ENOMEM; | 8021 | return -ENOMEM; |
@@ -7227,13 +8033,25 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) | |||
7227 | ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; | 8033 | ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; |
7228 | 8034 | ||
7229 | ioarcb = &ipr_cmd->ioarcb; | 8035 | ioarcb = &ipr_cmd->ioarcb; |
7230 | ioarcb->ioarcb_host_pci_addr = cpu_to_be32(dma_addr); | 8036 | ipr_cmd->dma_addr = dma_addr; |
8037 | if (ioa_cfg->sis64) | ||
8038 | ioarcb->a.ioarcb_host_pci_addr64 = cpu_to_be64(dma_addr); | ||
8039 | else | ||
8040 | ioarcb->a.ioarcb_host_pci_addr = cpu_to_be32(dma_addr); | ||
8041 | |||
7231 | ioarcb->host_response_handle = cpu_to_be32(i << 2); | 8042 | ioarcb->host_response_handle = cpu_to_be32(i << 2); |
7232 | ioarcb->write_ioadl_addr = | 8043 | if (ioa_cfg->sis64) { |
7233 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); | 8044 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
7234 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 8045 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); |
7235 | ioarcb->ioasa_host_pci_addr = | 8046 | ioarcb->u.sis64_addr_data.ioasa_host_pci_addr = |
7236 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); | 8047 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa)); |
8048 | } else { | ||
8049 | ioarcb->write_ioadl_addr = | ||
8050 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | ||
8051 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | ||
8052 | ioarcb->ioasa_host_pci_addr = | ||
8053 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); | ||
8054 | } | ||
7237 | ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); | 8055 | ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); |
7238 | ipr_cmd->cmd_index = i; | 8056 | ipr_cmd->cmd_index = i; |
7239 | ipr_cmd->ioa_cfg = ioa_cfg; | 8057 | ipr_cmd->ioa_cfg = ioa_cfg; |
@@ -7260,13 +8078,24 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
7260 | 8078 | ||
7261 | ENTER; | 8079 | ENTER; |
7262 | ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * | 8080 | ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * |
7263 | IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL); | 8081 | ioa_cfg->max_devs_supported, GFP_KERNEL); |
7264 | 8082 | ||
7265 | if (!ioa_cfg->res_entries) | 8083 | if (!ioa_cfg->res_entries) |
7266 | goto out; | 8084 | goto out; |
7267 | 8085 | ||
7268 | for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++) | 8086 | if (ioa_cfg->sis64) { |
8087 | ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) * | ||
8088 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
8089 | ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) * | ||
8090 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
8091 | ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) * | ||
8092 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
8093 | } | ||
8094 | |||
8095 | for (i = 0; i < ioa_cfg->max_devs_supported; i++) { | ||
7269 | list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); | 8096 | list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); |
8097 | ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg; | ||
8098 | } | ||
7270 | 8099 | ||
7271 | ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev, | 8100 | ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev, |
7272 | sizeof(struct ipr_misc_cbs), | 8101 | sizeof(struct ipr_misc_cbs), |
@@ -7285,11 +8114,11 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
7285 | if (!ioa_cfg->host_rrq) | 8114 | if (!ioa_cfg->host_rrq) |
7286 | goto out_ipr_free_cmd_blocks; | 8115 | goto out_ipr_free_cmd_blocks; |
7287 | 8116 | ||
7288 | ioa_cfg->cfg_table = pci_alloc_consistent(ioa_cfg->pdev, | 8117 | ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev, |
7289 | sizeof(struct ipr_config_table), | 8118 | ioa_cfg->cfg_table_size, |
7290 | &ioa_cfg->cfg_table_dma); | 8119 | &ioa_cfg->cfg_table_dma); |
7291 | 8120 | ||
7292 | if (!ioa_cfg->cfg_table) | 8121 | if (!ioa_cfg->u.cfg_table) |
7293 | goto out_free_host_rrq; | 8122 | goto out_free_host_rrq; |
7294 | 8123 | ||
7295 | for (i = 0; i < IPR_NUM_HCAMS; i++) { | 8124 | for (i = 0; i < IPR_NUM_HCAMS; i++) { |
@@ -7323,8 +8152,9 @@ out_free_hostrcb_dma: | |||
7323 | ioa_cfg->hostrcb[i], | 8152 | ioa_cfg->hostrcb[i], |
7324 | ioa_cfg->hostrcb_dma[i]); | 8153 | ioa_cfg->hostrcb_dma[i]); |
7325 | } | 8154 | } |
7326 | pci_free_consistent(pdev, sizeof(struct ipr_config_table), | 8155 | pci_free_consistent(pdev, ioa_cfg->cfg_table_size, |
7327 | ioa_cfg->cfg_table, ioa_cfg->cfg_table_dma); | 8156 | ioa_cfg->u.cfg_table, |
8157 | ioa_cfg->cfg_table_dma); | ||
7328 | out_free_host_rrq: | 8158 | out_free_host_rrq: |
7329 | pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, | 8159 | pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, |
7330 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); | 8160 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); |
@@ -7399,15 +8229,21 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, | |||
7399 | init_waitqueue_head(&ioa_cfg->reset_wait_q); | 8229 | init_waitqueue_head(&ioa_cfg->reset_wait_q); |
7400 | init_waitqueue_head(&ioa_cfg->msi_wait_q); | 8230 | init_waitqueue_head(&ioa_cfg->msi_wait_q); |
7401 | ioa_cfg->sdt_state = INACTIVE; | 8231 | ioa_cfg->sdt_state = INACTIVE; |
7402 | if (ipr_enable_cache) | ||
7403 | ioa_cfg->cache_state = CACHE_ENABLED; | ||
7404 | else | ||
7405 | ioa_cfg->cache_state = CACHE_DISABLED; | ||
7406 | 8232 | ||
7407 | ipr_initialize_bus_attr(ioa_cfg); | 8233 | ipr_initialize_bus_attr(ioa_cfg); |
8234 | ioa_cfg->max_devs_supported = ipr_max_devs; | ||
7408 | 8235 | ||
7409 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; | 8236 | if (ioa_cfg->sis64) { |
7410 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; | 8237 | host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; |
8238 | host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; | ||
8239 | if (ipr_max_devs > IPR_MAX_SIS64_DEVS) | ||
8240 | ioa_cfg->max_devs_supported = IPR_MAX_SIS64_DEVS; | ||
8241 | } else { | ||
8242 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; | ||
8243 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; | ||
8244 | if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS) | ||
8245 | ioa_cfg->max_devs_supported = IPR_MAX_PHYSICAL_DEVS; | ||
8246 | } | ||
7411 | host->max_channel = IPR_MAX_BUS_TO_SCAN; | 8247 | host->max_channel = IPR_MAX_BUS_TO_SCAN; |
7412 | host->unique_id = host->host_no; | 8248 | host->unique_id = host->host_no; |
7413 | host->max_cmd_len = IPR_MAX_CDB_LEN; | 8249 | host->max_cmd_len = IPR_MAX_CDB_LEN; |
@@ -7419,13 +8255,26 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, | |||
7419 | 8255 | ||
7420 | t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; | 8256 | t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; |
7421 | t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; | 8257 | t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; |
8258 | t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32; | ||
7422 | t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; | 8259 | t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; |
8260 | t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32; | ||
7423 | t->clr_interrupt_reg = base + p->clr_interrupt_reg; | 8261 | t->clr_interrupt_reg = base + p->clr_interrupt_reg; |
8262 | t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32; | ||
7424 | t->sense_interrupt_reg = base + p->sense_interrupt_reg; | 8263 | t->sense_interrupt_reg = base + p->sense_interrupt_reg; |
8264 | t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32; | ||
7425 | t->ioarrin_reg = base + p->ioarrin_reg; | 8265 | t->ioarrin_reg = base + p->ioarrin_reg; |
7426 | t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; | 8266 | t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; |
8267 | t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32; | ||
7427 | t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; | 8268 | t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; |
8269 | t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32; | ||
7428 | t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; | 8270 | t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; |
8271 | t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32; | ||
8272 | |||
8273 | if (ioa_cfg->sis64) { | ||
8274 | t->init_feedback_reg = base + p->init_feedback_reg; | ||
8275 | t->dump_addr_reg = base + p->dump_addr_reg; | ||
8276 | t->dump_data_reg = base + p->dump_data_reg; | ||
8277 | } | ||
7429 | } | 8278 | } |
7430 | 8279 | ||
7431 | /** | 8280 | /** |
@@ -7497,7 +8346,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, | |||
7497 | init_waitqueue_head(&ioa_cfg->msi_wait_q); | 8346 | init_waitqueue_head(&ioa_cfg->msi_wait_q); |
7498 | ioa_cfg->msi_received = 0; | 8347 | ioa_cfg->msi_received = 0; |
7499 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); | 8348 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); |
7500 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg); | 8349 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32); |
7501 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 8350 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
7502 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 8351 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
7503 | 8352 | ||
@@ -7508,7 +8357,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, | |||
7508 | } else if (ipr_debug) | 8357 | } else if (ipr_debug) |
7509 | dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); | 8358 | dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); |
7510 | 8359 | ||
7511 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg); | 8360 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32); |
7512 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); | 8361 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); |
7513 | wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); | 8362 | wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); |
7514 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); | 8363 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); |
@@ -7578,6 +8427,8 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7578 | goto out_scsi_host_put; | 8427 | goto out_scsi_host_put; |
7579 | } | 8428 | } |
7580 | 8429 | ||
8430 | /* set SIS 32 or SIS 64 */ | ||
8431 | ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0; | ||
7581 | ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; | 8432 | ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; |
7582 | 8433 | ||
7583 | if (ipr_transop_timeout) | 8434 | if (ipr_transop_timeout) |
@@ -7615,7 +8466,16 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7615 | 8466 | ||
7616 | pci_set_master(pdev); | 8467 | pci_set_master(pdev); |
7617 | 8468 | ||
7618 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 8469 | if (ioa_cfg->sis64) { |
8470 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); | ||
8471 | if (rc < 0) { | ||
8472 | dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n"); | ||
8473 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
8474 | } | ||
8475 | |||
8476 | } else | ||
8477 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
8478 | |||
7619 | if (rc < 0) { | 8479 | if (rc < 0) { |
7620 | dev_err(&pdev->dev, "Failed to set PCI DMA mask\n"); | 8480 | dev_err(&pdev->dev, "Failed to set PCI DMA mask\n"); |
7621 | goto cleanup_nomem; | 8481 | goto cleanup_nomem; |
@@ -7657,6 +8517,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7657 | if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg))) | 8517 | if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg))) |
7658 | goto cleanup_nomem; | 8518 | goto cleanup_nomem; |
7659 | 8519 | ||
8520 | if (ioa_cfg->sis64) | ||
8521 | ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr64) | ||
8522 | + ((sizeof(struct ipr_config_table_entry64) | ||
8523 | * ioa_cfg->max_devs_supported))); | ||
8524 | else | ||
8525 | ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr) | ||
8526 | + ((sizeof(struct ipr_config_table_entry) | ||
8527 | * ioa_cfg->max_devs_supported))); | ||
8528 | |||
7660 | rc = ipr_alloc_mem(ioa_cfg); | 8529 | rc = ipr_alloc_mem(ioa_cfg); |
7661 | if (rc < 0) { | 8530 | if (rc < 0) { |
7662 | dev_err(&pdev->dev, | 8531 | dev_err(&pdev->dev, |
@@ -7668,9 +8537,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7668 | * If HRRQ updated interrupt is not masked, or reset alert is set, | 8537 | * If HRRQ updated interrupt is not masked, or reset alert is set, |
7669 | * the card is in an unknown state and needs a hard reset | 8538 | * the card is in an unknown state and needs a hard reset |
7670 | */ | 8539 | */ |
7671 | mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 8540 | mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); |
7672 | interrupts = readl(ioa_cfg->regs.sense_interrupt_reg); | 8541 | interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32); |
7673 | uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg); | 8542 | uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); |
7674 | if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) | 8543 | if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) |
7675 | ioa_cfg->needs_hard_reset = 1; | 8544 | ioa_cfg->needs_hard_reset = 1; |
7676 | if (interrupts & IPR_PCII_ERROR_INTERRUPTS) | 8545 | if (interrupts & IPR_PCII_ERROR_INTERRUPTS) |
@@ -7958,9 +8827,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { | |||
7958 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, | 8827 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, |
7959 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | 8828 | IPR_USE_LONG_TRANSOP_TIMEOUT }, |
7960 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | 8829 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, |
7961 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, | ||
7962 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | ||
7963 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | ||
7964 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, | 8830 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, |
7965 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | 8831 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, |
7966 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, | 8832 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, |
@@ -7975,9 +8841,22 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { | |||
7975 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, | 8841 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, |
7976 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, | 8842 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, |
7977 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | 8843 | IPR_USE_LONG_TRANSOP_TIMEOUT }, |
7978 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E, | 8844 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, |
7979 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, | 8845 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B5, 0, 0, 0 }, |
7980 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | 8846 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, |
8847 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 }, | ||
8848 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, | ||
8849 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 }, | ||
8850 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8851 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 }, | ||
8852 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8853 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B1, 0, 0, 0 }, | ||
8854 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8855 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C6, 0, 0, 0 }, | ||
8856 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8857 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, 0 }, | ||
8858 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8859 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57CE, 0, 0, 0 }, | ||
7981 | { } | 8860 | { } |
7982 | }; | 8861 | }; |
7983 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); | 8862 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); |
@@ -7997,6 +8876,61 @@ static struct pci_driver ipr_driver = { | |||
7997 | }; | 8876 | }; |
7998 | 8877 | ||
7999 | /** | 8878 | /** |
8879 | * ipr_halt_done - Shutdown prepare completion | ||
8880 | * | ||
8881 | * Return value: | ||
8882 | * none | ||
8883 | **/ | ||
8884 | static void ipr_halt_done(struct ipr_cmnd *ipr_cmd) | ||
8885 | { | ||
8886 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
8887 | |||
8888 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | ||
8889 | } | ||
8890 | |||
8891 | /** | ||
8892 | * ipr_halt - Issue shutdown prepare to all adapters | ||
8893 | * | ||
8894 | * Return value: | ||
8895 | * NOTIFY_OK on success / NOTIFY_DONE on failure | ||
8896 | **/ | ||
8897 | static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) | ||
8898 | { | ||
8899 | struct ipr_cmnd *ipr_cmd; | ||
8900 | struct ipr_ioa_cfg *ioa_cfg; | ||
8901 | unsigned long flags = 0; | ||
8902 | |||
8903 | if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) | ||
8904 | return NOTIFY_DONE; | ||
8905 | |||
8906 | spin_lock(&ipr_driver_lock); | ||
8907 | |||
8908 | list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { | ||
8909 | spin_lock_irqsave(ioa_cfg->host->host_lock, flags); | ||
8910 | if (!ioa_cfg->allow_cmds) { | ||
8911 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | ||
8912 | continue; | ||
8913 | } | ||
8914 | |||
8915 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | ||
8916 | ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | ||
8917 | ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | ||
8918 | ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; | ||
8919 | ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; | ||
8920 | |||
8921 | ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); | ||
8922 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | ||
8923 | } | ||
8924 | spin_unlock(&ipr_driver_lock); | ||
8925 | |||
8926 | return NOTIFY_OK; | ||
8927 | } | ||
8928 | |||
8929 | static struct notifier_block ipr_notifier = { | ||
8930 | ipr_halt, NULL, 0 | ||
8931 | }; | ||
8932 | |||
8933 | /** | ||
8000 | * ipr_init - Module entry point | 8934 | * ipr_init - Module entry point |
8001 | * | 8935 | * |
8002 | * Return value: | 8936 | * Return value: |
@@ -8007,6 +8941,7 @@ static int __init ipr_init(void) | |||
8007 | ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", | 8941 | ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", |
8008 | IPR_DRIVER_VERSION, IPR_DRIVER_DATE); | 8942 | IPR_DRIVER_VERSION, IPR_DRIVER_DATE); |
8009 | 8943 | ||
8944 | register_reboot_notifier(&ipr_notifier); | ||
8010 | return pci_register_driver(&ipr_driver); | 8945 | return pci_register_driver(&ipr_driver); |
8011 | } | 8946 | } |
8012 | 8947 | ||
@@ -8020,6 +8955,7 @@ static int __init ipr_init(void) | |||
8020 | **/ | 8955 | **/ |
8021 | static void __exit ipr_exit(void) | 8956 | static void __exit ipr_exit(void) |
8022 | { | 8957 | { |
8958 | unregister_reboot_notifier(&ipr_notifier); | ||
8023 | pci_unregister_driver(&ipr_driver); | 8959 | pci_unregister_driver(&ipr_driver); |
8024 | } | 8960 | } |
8025 | 8961 | ||