diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-23 19:37:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-23 19:37:29 -0400 |
commit | 1212663fba7c5e003e05d24f043d5ed57eb18b24 (patch) | |
tree | d6d1327b1e852721952e2efc8aabca25e73573f0 /drivers/scsi/sym53c8xx_2 | |
parent | af76bbabbdf5cebea6a3863446f9f74b469c4bdc (diff) | |
parent | af2709fd0d127cd590e7a77ab50b23cdb9f6f48f (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (39 commits)
[SCSI] qla2xxx: Update version number to 8.02.00-k5.
[SCSI] qla2xxx: Correct display of ISP serial-number.
[SCSI] qla2xxx: Correct residual-count handling discrepancies during UNDERRUN handling.
[SCSI] qla2xxx: Make driver (mostly) legacy I/O port free.
[SCSI] qla2xxx: Fix issue where final flash-segment updates were falling into the slow-path write handler.
[SCSI] qla2xxx: Handle unaligned sector writes during NVRAM/VPD updates.
[SCSI] qla2xxx: Defer explicit interrupt-polling processing to init-time scenarios.
[SCSI] qla2xxx: Resync with latest HBA SSID specification -- 2.2u.
[SCSI] sym53c8xx: Remove sym_xpt_async_sent_bdr
[SCSI] sym53c8xx: Remove pci_dev pointer from sym_shcb
[SCSI] sym53c8xx: Make interrupt handler capable of returning IRQ_NONE
[SCSI] sym53c8xx: Get rid of IRQ_FMT and IRQ_PRM
[SCSI] sym53c8xx: Use scmd_printk where appropriate
[SCSI] sym53c8xx: Simplify DAC DMA handling
[SCSI] sym53c8xx: Remove tag_ctrl module parameter
[SCSI] sym53c8xx: Remove io_ws, mmio_ws and ram_ws elements
[SCSI] sym53c8xx: Remove ->device_id
[SCSI] sym53c8xx: Use pdev->revision
[SCSI] sym53c8xx: PCI Error Recovery support
[SCSI] sym53c8xx: Stop overriding scsi_done
...
Diffstat (limited to 'drivers/scsi/sym53c8xx_2')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym53c8xx.h | 1 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_fw.c | 18 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_fw.h | 2 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 581 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.h | 16 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_hipd.c | 159 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_hipd.h | 22 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_nvram.c | 2 |
8 files changed, 416 insertions, 385 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym53c8xx.h b/drivers/scsi/sym53c8xx_2/sym53c8xx.h index 7519728dfc38..62d29cfac9e4 100644 --- a/drivers/scsi/sym53c8xx_2/sym53c8xx.h +++ b/drivers/scsi/sym53c8xx_2/sym53c8xx.h | |||
@@ -127,7 +127,6 @@ struct sym_driver_setup { | |||
127 | u_char settle_delay; | 127 | u_char settle_delay; |
128 | u_char use_nvram; | 128 | u_char use_nvram; |
129 | u_long excludes[8]; | 129 | u_long excludes[8]; |
130 | char tag_ctrl[100]; | ||
131 | }; | 130 | }; |
132 | 131 | ||
133 | #define SYM_SETUP_MAX_TAG sym_driver_setup.max_tag | 132 | #define SYM_SETUP_MAX_TAG sym_driver_setup.max_tag |
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c index 9916a2a22558..190770bdc194 100644 --- a/drivers/scsi/sym53c8xx_2/sym_fw.c +++ b/drivers/scsi/sym53c8xx_2/sym_fw.c | |||
@@ -104,8 +104,9 @@ static struct sym_fwz_ofs sym_fw2z_ofs = { | |||
104 | * Patch routine for firmware #1. | 104 | * Patch routine for firmware #1. |
105 | */ | 105 | */ |
106 | static void | 106 | static void |
107 | sym_fw1_patch(struct sym_hcb *np) | 107 | sym_fw1_patch(struct Scsi_Host *shost) |
108 | { | 108 | { |
109 | struct sym_hcb *np = sym_get_hcb(shost); | ||
109 | struct sym_fw1a_scr *scripta0; | 110 | struct sym_fw1a_scr *scripta0; |
110 | struct sym_fw1b_scr *scriptb0; | 111 | struct sym_fw1b_scr *scriptb0; |
111 | 112 | ||
@@ -145,8 +146,11 @@ sym_fw1_patch(struct sym_hcb *np) | |||
145 | * Patch routine for firmware #2. | 146 | * Patch routine for firmware #2. |
146 | */ | 147 | */ |
147 | static void | 148 | static void |
148 | sym_fw2_patch(struct sym_hcb *np) | 149 | sym_fw2_patch(struct Scsi_Host *shost) |
149 | { | 150 | { |
151 | struct sym_data *sym_data = shost_priv(shost); | ||
152 | struct pci_dev *pdev = sym_data->pdev; | ||
153 | struct sym_hcb *np = sym_data->ncb; | ||
150 | struct sym_fw2a_scr *scripta0; | 154 | struct sym_fw2a_scr *scripta0; |
151 | struct sym_fw2b_scr *scriptb0; | 155 | struct sym_fw2b_scr *scriptb0; |
152 | 156 | ||
@@ -167,7 +171,7 @@ sym_fw2_patch(struct sym_hcb *np) | |||
167 | * Remove useless 64 bit DMA specific SCRIPTS, | 171 | * Remove useless 64 bit DMA specific SCRIPTS, |
168 | * when this feature is not available. | 172 | * when this feature is not available. |
169 | */ | 173 | */ |
170 | if (!np->use_dac) { | 174 | if (!use_dac(np)) { |
171 | scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP); | 175 | scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP); |
172 | scripta0->is_dmap_dirty[1] = 0; | 176 | scripta0->is_dmap_dirty[1] = 0; |
173 | scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP); | 177 | scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP); |
@@ -205,14 +209,14 @@ sym_fw2_patch(struct sym_hcb *np) | |||
205 | * Remove a couple of work-arounds specific to C1010 if | 209 | * Remove a couple of work-arounds specific to C1010 if |
206 | * they are not desirable. See `sym_fw2.h' for more details. | 210 | * they are not desirable. See `sym_fw2.h' for more details. |
207 | */ | 211 | */ |
208 | if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 && | 212 | if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_66 && |
209 | np->revision_id < 0x1 && | 213 | pdev->revision < 0x1 && |
210 | np->pciclk_khz < 60000)) { | 214 | np->pciclk_khz < 60000)) { |
211 | scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); | 215 | scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); |
212 | scripta0->datao_phase[1] = cpu_to_scr(0); | 216 | scripta0->datao_phase[1] = cpu_to_scr(0); |
213 | } | 217 | } |
214 | if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && | 218 | if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 /* && |
215 | /* np->revision_id < 0xff */ 1)) { | 219 | pdev->revision < 0xff */)) { |
216 | scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); | 220 | scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); |
217 | scripta0->sel_done[1] = cpu_to_scr(0); | 221 | scripta0->sel_done[1] = cpu_to_scr(0); |
218 | } | 222 | } |
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.h b/drivers/scsi/sym53c8xx_2/sym_fw.h index 66ec35beab5b..ae7e0f9e93fc 100644 --- a/drivers/scsi/sym53c8xx_2/sym_fw.h +++ b/drivers/scsi/sym53c8xx_2/sym_fw.h | |||
@@ -143,7 +143,7 @@ struct sym_fw { | |||
143 | *z_ofs; /* Useful offsets in script Z */ | 143 | *z_ofs; /* Useful offsets in script Z */ |
144 | /* Setup and patch methods for this firmware */ | 144 | /* Setup and patch methods for this firmware */ |
145 | void (*setup)(struct sym_hcb *, struct sym_fw *); | 145 | void (*setup)(struct sym_hcb *, struct sym_fw *); |
146 | void (*patch)(struct sym_hcb *); | 146 | void (*patch)(struct Scsi_Host *); |
147 | }; | 147 | }; |
148 | 148 | ||
149 | /* | 149 | /* |
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index db03c4c8ec1e..0f74aba5b237 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -39,7 +39,6 @@ | |||
39 | */ | 39 | */ |
40 | #include <linux/ctype.h> | 40 | #include <linux/ctype.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/module.h> | 42 | #include <linux/module.h> |
44 | #include <linux/moduleparam.h> | 43 | #include <linux/moduleparam.h> |
45 | #include <linux/spinlock.h> | 44 | #include <linux/spinlock.h> |
@@ -54,16 +53,12 @@ | |||
54 | #define NAME53C "sym53c" | 53 | #define NAME53C "sym53c" |
55 | #define NAME53C8XX "sym53c8xx" | 54 | #define NAME53C8XX "sym53c8xx" |
56 | 55 | ||
57 | #define IRQ_FMT "%d" | ||
58 | #define IRQ_PRM(x) (x) | ||
59 | |||
60 | struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP; | 56 | struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP; |
61 | unsigned int sym_debug_flags = 0; | 57 | unsigned int sym_debug_flags = 0; |
62 | 58 | ||
63 | static char *excl_string; | 59 | static char *excl_string; |
64 | static char *safe_string; | 60 | static char *safe_string; |
65 | module_param_named(cmd_per_lun, sym_driver_setup.max_tag, ushort, 0); | 61 | module_param_named(cmd_per_lun, sym_driver_setup.max_tag, ushort, 0); |
66 | module_param_string(tag_ctrl, sym_driver_setup.tag_ctrl, 100, 0); | ||
67 | module_param_named(burst, sym_driver_setup.burst_order, byte, 0); | 62 | module_param_named(burst, sym_driver_setup.burst_order, byte, 0); |
68 | module_param_named(led, sym_driver_setup.scsi_led, byte, 0); | 63 | module_param_named(led, sym_driver_setup.scsi_led, byte, 0); |
69 | module_param_named(diff, sym_driver_setup.scsi_diff, byte, 0); | 64 | module_param_named(diff, sym_driver_setup.scsi_diff, byte, 0); |
@@ -78,7 +73,6 @@ module_param_named(excl, excl_string, charp, 0); | |||
78 | module_param_named(safe, safe_string, charp, 0); | 73 | module_param_named(safe, safe_string, charp, 0); |
79 | 74 | ||
80 | MODULE_PARM_DESC(cmd_per_lun, "The maximum number of tags to use by default"); | 75 | MODULE_PARM_DESC(cmd_per_lun, "The maximum number of tags to use by default"); |
81 | MODULE_PARM_DESC(tag_ctrl, "More detailed control over tags per LUN"); | ||
82 | MODULE_PARM_DESC(burst, "Maximum burst. 0 to disable, 255 to read from registers"); | 76 | MODULE_PARM_DESC(burst, "Maximum burst. 0 to disable, 255 to read from registers"); |
83 | MODULE_PARM_DESC(led, "Set to 1 to enable LED support"); | 77 | MODULE_PARM_DESC(led, "Set to 1 to enable LED support"); |
84 | MODULE_PARM_DESC(diff, "0 for no differential mode, 1 for BIOS, 2 for always, 3 for not GPIO3"); | 78 | MODULE_PARM_DESC(diff, "0 for no differential mode, 1 for BIOS, 2 for always, 3 for not GPIO3"); |
@@ -134,56 +128,26 @@ static struct scsi_transport_template *sym2_transport_template = NULL; | |||
134 | * Driver private area in the SCSI command structure. | 128 | * Driver private area in the SCSI command structure. |
135 | */ | 129 | */ |
136 | struct sym_ucmd { /* Override the SCSI pointer structure */ | 130 | struct sym_ucmd { /* Override the SCSI pointer structure */ |
137 | dma_addr_t data_mapping; | 131 | struct completion *eh_done; /* SCSI error handling */ |
138 | unsigned char data_mapped; | ||
139 | unsigned char to_do; /* For error handling */ | ||
140 | void (*old_done)(struct scsi_cmnd *); /* For error handling */ | ||
141 | struct completion *eh_done; /* For error handling */ | ||
142 | }; | 132 | }; |
143 | 133 | ||
144 | #define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp)) | 134 | #define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp)) |
145 | #define SYM_SOFTC_PTR(cmd) sym_get_hcb(cmd->device->host) | 135 | #define SYM_SOFTC_PTR(cmd) sym_get_hcb(cmd->device->host) |
146 | 136 | ||
147 | static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) | ||
148 | { | ||
149 | if (SYM_UCMD_PTR(cmd)->data_mapped) | ||
150 | scsi_dma_unmap(cmd); | ||
151 | |||
152 | SYM_UCMD_PTR(cmd)->data_mapped = 0; | ||
153 | } | ||
154 | |||
155 | static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) | ||
156 | { | ||
157 | int use_sg; | ||
158 | |||
159 | use_sg = scsi_dma_map(cmd); | ||
160 | if (use_sg > 0) { | ||
161 | SYM_UCMD_PTR(cmd)->data_mapped = 2; | ||
162 | SYM_UCMD_PTR(cmd)->data_mapping = use_sg; | ||
163 | } | ||
164 | |||
165 | return use_sg; | ||
166 | } | ||
167 | |||
168 | #define unmap_scsi_data(np, cmd) \ | ||
169 | __unmap_scsi_data(np->s.device, cmd) | ||
170 | #define map_scsi_sg_data(np, cmd) \ | ||
171 | __map_scsi_sg_data(np->s.device, cmd) | ||
172 | /* | 137 | /* |
173 | * Complete a pending CAM CCB. | 138 | * Complete a pending CAM CCB. |
174 | */ | 139 | */ |
175 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd) | 140 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd) |
176 | { | 141 | { |
177 | unmap_scsi_data(np, cmd); | 142 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); |
178 | cmd->scsi_done(cmd); | 143 | BUILD_BUG_ON(sizeof(struct scsi_pointer) < sizeof(struct sym_ucmd)); |
179 | } | ||
180 | 144 | ||
181 | static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *cmd, int cam_status) | 145 | if (ucmd->eh_done) |
182 | { | 146 | complete(ucmd->eh_done); |
183 | sym_set_cam_status(cmd, cam_status); | ||
184 | sym_xpt_done(np, cmd); | ||
185 | } | ||
186 | 147 | ||
148 | scsi_dma_unmap(cmd); | ||
149 | cmd->scsi_done(cmd); | ||
150 | } | ||
187 | 151 | ||
188 | /* | 152 | /* |
189 | * Tell the SCSI layer about a BUS RESET. | 153 | * Tell the SCSI layer about a BUS RESET. |
@@ -199,14 +163,6 @@ void sym_xpt_async_bus_reset(struct sym_hcb *np) | |||
199 | } | 163 | } |
200 | 164 | ||
201 | /* | 165 | /* |
202 | * Tell the SCSI layer about a BUS DEVICE RESET message sent. | ||
203 | */ | ||
204 | void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target) | ||
205 | { | ||
206 | printf_notice("%s: TARGET %d has been reset.\n", sym_name(np), target); | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Choose the more appropriate CAM status if | 166 | * Choose the more appropriate CAM status if |
211 | * the IO encountered an extended error. | 167 | * the IO encountered an extended error. |
212 | */ | 168 | */ |
@@ -307,14 +263,14 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd | |||
307 | 263 | ||
308 | cp->data_len = 0; | 264 | cp->data_len = 0; |
309 | 265 | ||
310 | use_sg = map_scsi_sg_data(np, cmd); | 266 | use_sg = scsi_dma_map(cmd); |
311 | if (use_sg > 0) { | 267 | if (use_sg > 0) { |
312 | struct scatterlist *sg; | 268 | struct scatterlist *sg; |
313 | struct sym_tcb *tp = &np->target[cp->target]; | 269 | struct sym_tcb *tp = &np->target[cp->target]; |
314 | struct sym_tblmove *data; | 270 | struct sym_tblmove *data; |
315 | 271 | ||
316 | if (use_sg > SYM_CONF_MAX_SG) { | 272 | if (use_sg > SYM_CONF_MAX_SG) { |
317 | unmap_scsi_data(np, cmd); | 273 | scsi_dma_unmap(cmd); |
318 | return -1; | 274 | return -1; |
319 | } | 275 | } |
320 | 276 | ||
@@ -351,15 +307,6 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd) | |||
351 | int order; | 307 | int order; |
352 | 308 | ||
353 | /* | 309 | /* |
354 | * Minimal checkings, so that we will not | ||
355 | * go outside our tables. | ||
356 | */ | ||
357 | if (sdev->id == np->myaddr) { | ||
358 | sym_xpt_done2(np, cmd, DID_NO_CONNECT); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * Retrieve the target descriptor. | 310 | * Retrieve the target descriptor. |
364 | */ | 311 | */ |
365 | tp = &np->target[sdev->id]; | 312 | tp = &np->target[sdev->id]; |
@@ -433,7 +380,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s | |||
433 | */ | 380 | */ |
434 | switch (dir) { | 381 | switch (dir) { |
435 | case DMA_BIDIRECTIONAL: | 382 | case DMA_BIDIRECTIONAL: |
436 | printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np)); | 383 | scmd_printk(KERN_INFO, cmd, "got DMA_BIDIRECTIONAL command"); |
437 | sym_set_cam_status(cmd, DID_ERROR); | 384 | sym_set_cam_status(cmd, DID_ERROR); |
438 | goto out_abort; | 385 | goto out_abort; |
439 | case DMA_TO_DEVICE: | 386 | case DMA_TO_DEVICE: |
@@ -542,14 +489,16 @@ static void sym_timer(struct sym_hcb *np) | |||
542 | /* | 489 | /* |
543 | * PCI BUS error handler. | 490 | * PCI BUS error handler. |
544 | */ | 491 | */ |
545 | void sym_log_bus_error(struct sym_hcb *np) | 492 | void sym_log_bus_error(struct Scsi_Host *shost) |
546 | { | 493 | { |
547 | u_short pci_sts; | 494 | struct sym_data *sym_data = shost_priv(shost); |
548 | pci_read_config_word(np->s.device, PCI_STATUS, &pci_sts); | 495 | struct pci_dev *pdev = sym_data->pdev; |
496 | unsigned short pci_sts; | ||
497 | pci_read_config_word(pdev, PCI_STATUS, &pci_sts); | ||
549 | if (pci_sts & 0xf900) { | 498 | if (pci_sts & 0xf900) { |
550 | pci_write_config_word(np->s.device, PCI_STATUS, pci_sts); | 499 | pci_write_config_word(pdev, PCI_STATUS, pci_sts); |
551 | printf("%s: PCI STATUS = 0x%04x\n", | 500 | shost_printk(KERN_WARNING, shost, |
552 | sym_name(np), pci_sts & 0xf900); | 501 | "PCI bus error: status = 0x%04x\n", pci_sts & 0xf900); |
553 | } | 502 | } |
554 | } | 503 | } |
555 | 504 | ||
@@ -564,7 +513,7 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd, | |||
564 | struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd); | 513 | struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd); |
565 | int sts = 0; | 514 | int sts = 0; |
566 | 515 | ||
567 | cmd->scsi_done = done; | 516 | cmd->scsi_done = done; |
568 | memset(ucp, 0, sizeof(*ucp)); | 517 | memset(ucp, 0, sizeof(*ucp)); |
569 | 518 | ||
570 | /* | 519 | /* |
@@ -593,18 +542,23 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd, | |||
593 | */ | 542 | */ |
594 | static irqreturn_t sym53c8xx_intr(int irq, void *dev_id) | 543 | static irqreturn_t sym53c8xx_intr(int irq, void *dev_id) |
595 | { | 544 | { |
596 | unsigned long flags; | 545 | struct Scsi_Host *shost = dev_id; |
597 | struct sym_hcb *np = (struct sym_hcb *)dev_id; | 546 | struct sym_data *sym_data = shost_priv(shost); |
547 | irqreturn_t result; | ||
548 | |||
549 | /* Avoid spinloop trying to handle interrupts on frozen device */ | ||
550 | if (pci_channel_offline(sym_data->pdev)) | ||
551 | return IRQ_NONE; | ||
598 | 552 | ||
599 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); | 553 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); |
600 | 554 | ||
601 | spin_lock_irqsave(np->s.host->host_lock, flags); | 555 | spin_lock(shost->host_lock); |
602 | sym_interrupt(np); | 556 | result = sym_interrupt(shost); |
603 | spin_unlock_irqrestore(np->s.host->host_lock, flags); | 557 | spin_unlock(shost->host_lock); |
604 | 558 | ||
605 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n"); | 559 | if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n"); |
606 | 560 | ||
607 | return IRQ_HANDLED; | 561 | return result; |
608 | } | 562 | } |
609 | 563 | ||
610 | /* | 564 | /* |
@@ -630,59 +584,61 @@ static void sym53c8xx_timer(unsigned long npref) | |||
630 | #define SYM_EH_HOST_RESET 3 | 584 | #define SYM_EH_HOST_RESET 3 |
631 | 585 | ||
632 | /* | 586 | /* |
633 | * What we will do regarding the involved SCSI command. | ||
634 | */ | ||
635 | #define SYM_EH_DO_IGNORE 0 | ||
636 | #define SYM_EH_DO_WAIT 2 | ||
637 | |||
638 | /* | ||
639 | * scsi_done() alias when error recovery is in progress. | ||
640 | */ | ||
641 | static void sym_eh_done(struct scsi_cmnd *cmd) | ||
642 | { | ||
643 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); | ||
644 | BUILD_BUG_ON(sizeof(struct scsi_pointer) < sizeof(struct sym_ucmd)); | ||
645 | |||
646 | cmd->scsi_done = ucmd->old_done; | ||
647 | |||
648 | if (ucmd->to_do == SYM_EH_DO_WAIT) | ||
649 | complete(ucmd->eh_done); | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * Generic method for our eh processing. | 587 | * Generic method for our eh processing. |
654 | * The 'op' argument tells what we have to do. | 588 | * The 'op' argument tells what we have to do. |
655 | */ | 589 | */ |
656 | static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) | 590 | static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) |
657 | { | 591 | { |
658 | struct sym_hcb *np = SYM_SOFTC_PTR(cmd); | ||
659 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); | 592 | struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd); |
660 | struct Scsi_Host *host = cmd->device->host; | 593 | struct Scsi_Host *shost = cmd->device->host; |
594 | struct sym_data *sym_data = shost_priv(shost); | ||
595 | struct pci_dev *pdev = sym_data->pdev; | ||
596 | struct sym_hcb *np = sym_data->ncb; | ||
661 | SYM_QUEHEAD *qp; | 597 | SYM_QUEHEAD *qp; |
662 | int to_do = SYM_EH_DO_IGNORE; | 598 | int cmd_queued = 0; |
663 | int sts = -1; | 599 | int sts = -1; |
664 | struct completion eh_done; | 600 | struct completion eh_done; |
665 | 601 | ||
666 | dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname); | 602 | scmd_printk(KERN_WARNING, cmd, "%s operation started\n", opname); |
603 | |||
604 | /* We may be in an error condition because the PCI bus | ||
605 | * went down. In this case, we need to wait until the | ||
606 | * PCI bus is reset, the card is reset, and only then | ||
607 | * proceed with the scsi error recovery. There's no | ||
608 | * point in hurrying; take a leisurely wait. | ||
609 | */ | ||
610 | #define WAIT_FOR_PCI_RECOVERY 35 | ||
611 | if (pci_channel_offline(pdev)) { | ||
612 | struct completion *io_reset; | ||
613 | int finished_reset = 0; | ||
614 | init_completion(&eh_done); | ||
615 | spin_lock_irq(shost->host_lock); | ||
616 | /* Make sure we didn't race */ | ||
617 | if (pci_channel_offline(pdev)) { | ||
618 | if (!sym_data->io_reset) | ||
619 | sym_data->io_reset = &eh_done; | ||
620 | io_reset = sym_data->io_reset; | ||
621 | } else { | ||
622 | finished_reset = 1; | ||
623 | } | ||
624 | spin_unlock_irq(shost->host_lock); | ||
625 | if (!finished_reset) | ||
626 | finished_reset = wait_for_completion_timeout(io_reset, | ||
627 | WAIT_FOR_PCI_RECOVERY*HZ); | ||
628 | if (!finished_reset) | ||
629 | return SCSI_FAILED; | ||
630 | } | ||
667 | 631 | ||
668 | spin_lock_irq(host->host_lock); | 632 | spin_lock_irq(shost->host_lock); |
669 | /* This one is queued in some place -> to wait for completion */ | 633 | /* This one is queued in some place -> to wait for completion */ |
670 | FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { | 634 | FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { |
671 | struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); | 635 | struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); |
672 | if (cp->cmd == cmd) { | 636 | if (cp->cmd == cmd) { |
673 | to_do = SYM_EH_DO_WAIT; | 637 | cmd_queued = 1; |
674 | break; | 638 | break; |
675 | } | 639 | } |
676 | } | 640 | } |
677 | 641 | ||
678 | if (to_do == SYM_EH_DO_WAIT) { | ||
679 | init_completion(&eh_done); | ||
680 | ucmd->old_done = cmd->scsi_done; | ||
681 | ucmd->eh_done = &eh_done; | ||
682 | wmb(); | ||
683 | cmd->scsi_done = sym_eh_done; | ||
684 | } | ||
685 | |||
686 | /* Try to proceed the operation we have been asked for */ | 642 | /* Try to proceed the operation we have been asked for */ |
687 | sts = -1; | 643 | sts = -1; |
688 | switch(op) { | 644 | switch(op) { |
@@ -698,7 +654,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) | |||
698 | break; | 654 | break; |
699 | case SYM_EH_HOST_RESET: | 655 | case SYM_EH_HOST_RESET: |
700 | sym_reset_scsi_bus(np, 0); | 656 | sym_reset_scsi_bus(np, 0); |
701 | sym_start_up (np, 1); | 657 | sym_start_up(shost, 1); |
702 | sts = 0; | 658 | sts = 0; |
703 | break; | 659 | break; |
704 | default: | 660 | default: |
@@ -706,21 +662,21 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd) | |||
706 | } | 662 | } |
707 | 663 | ||
708 | /* On error, restore everything and cross fingers :) */ | 664 | /* On error, restore everything and cross fingers :) */ |
709 | if (sts) { | 665 | if (sts) |
710 | cmd->scsi_done = ucmd->old_done; | 666 | cmd_queued = 0; |
711 | to_do = SYM_EH_DO_IGNORE; | ||
712 | } | ||
713 | |||
714 | ucmd->to_do = to_do; | ||
715 | spin_unlock_irq(host->host_lock); | ||
716 | 667 | ||
717 | if (to_do == SYM_EH_DO_WAIT) { | 668 | if (cmd_queued) { |
669 | init_completion(&eh_done); | ||
670 | ucmd->eh_done = &eh_done; | ||
671 | spin_unlock_irq(shost->host_lock); | ||
718 | if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { | 672 | if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { |
719 | ucmd->to_do = SYM_EH_DO_IGNORE; | 673 | ucmd->eh_done = NULL; |
720 | wmb(); | ||
721 | sts = -2; | 674 | sts = -2; |
722 | } | 675 | } |
676 | } else { | ||
677 | spin_unlock_irq(shost->host_lock); | ||
723 | } | 678 | } |
679 | |||
724 | dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname, | 680 | dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname, |
725 | sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); | 681 | sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); |
726 | return sts ? SCSI_FAILED : SCSI_SUCCESS; | 682 | return sts ? SCSI_FAILED : SCSI_SUCCESS; |
@@ -775,59 +731,6 @@ static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags) | |||
775 | } | 731 | } |
776 | } | 732 | } |
777 | 733 | ||
778 | /* | ||
779 | * Linux select queue depths function | ||
780 | */ | ||
781 | #define DEF_DEPTH (sym_driver_setup.max_tag) | ||
782 | #define ALL_TARGETS -2 | ||
783 | #define NO_TARGET -1 | ||
784 | #define ALL_LUNS -2 | ||
785 | #define NO_LUN -1 | ||
786 | |||
787 | static int device_queue_depth(struct sym_hcb *np, int target, int lun) | ||
788 | { | ||
789 | int c, h, t, u, v; | ||
790 | char *p = sym_driver_setup.tag_ctrl; | ||
791 | char *ep; | ||
792 | |||
793 | h = -1; | ||
794 | t = NO_TARGET; | ||
795 | u = NO_LUN; | ||
796 | while ((c = *p++) != 0) { | ||
797 | v = simple_strtoul(p, &ep, 0); | ||
798 | switch(c) { | ||
799 | case '/': | ||
800 | ++h; | ||
801 | t = ALL_TARGETS; | ||
802 | u = ALL_LUNS; | ||
803 | break; | ||
804 | case 't': | ||
805 | if (t != target) | ||
806 | t = (target == v) ? v : NO_TARGET; | ||
807 | u = ALL_LUNS; | ||
808 | break; | ||
809 | case 'u': | ||
810 | if (u != lun) | ||
811 | u = (lun == v) ? v : NO_LUN; | ||
812 | break; | ||
813 | case 'q': | ||
814 | if (h == np->s.unit && | ||
815 | (t == ALL_TARGETS || t == target) && | ||
816 | (u == ALL_LUNS || u == lun)) | ||
817 | return v; | ||
818 | break; | ||
819 | case '-': | ||
820 | t = ALL_TARGETS; | ||
821 | u = ALL_LUNS; | ||
822 | break; | ||
823 | default: | ||
824 | break; | ||
825 | } | ||
826 | p = ep; | ||
827 | } | ||
828 | return DEF_DEPTH; | ||
829 | } | ||
830 | |||
831 | static int sym53c8xx_slave_alloc(struct scsi_device *sdev) | 734 | static int sym53c8xx_slave_alloc(struct scsi_device *sdev) |
832 | { | 735 | { |
833 | struct sym_hcb *np = sym_get_hcb(sdev->host); | 736 | struct sym_hcb *np = sym_get_hcb(sdev->host); |
@@ -892,21 +795,16 @@ static int sym53c8xx_slave_configure(struct scsi_device *sdev) | |||
892 | * Use at least 2. | 795 | * Use at least 2. |
893 | * Donnot use more than our maximum. | 796 | * Donnot use more than our maximum. |
894 | */ | 797 | */ |
895 | reqtags = device_queue_depth(np, sdev->id, sdev->lun); | 798 | reqtags = sym_driver_setup.max_tag; |
896 | if (reqtags > tp->usrtags) | 799 | if (reqtags > tp->usrtags) |
897 | reqtags = tp->usrtags; | 800 | reqtags = tp->usrtags; |
898 | if (!sdev->tagged_supported) | 801 | if (!sdev->tagged_supported) |
899 | reqtags = 0; | 802 | reqtags = 0; |
900 | #if 1 /* Avoid to locally queue commands for no good reasons */ | ||
901 | if (reqtags > SYM_CONF_MAX_TAG) | 803 | if (reqtags > SYM_CONF_MAX_TAG) |
902 | reqtags = SYM_CONF_MAX_TAG; | 804 | reqtags = SYM_CONF_MAX_TAG; |
903 | depth_to_use = (reqtags ? reqtags : 2); | 805 | depth_to_use = reqtags ? reqtags : 2; |
904 | #else | ||
905 | depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2); | ||
906 | #endif | ||
907 | scsi_adjust_queue_depth(sdev, | 806 | scsi_adjust_queue_depth(sdev, |
908 | (sdev->tagged_supported ? | 807 | sdev->tagged_supported ? MSG_SIMPLE_TAG : 0, |
909 | MSG_SIMPLE_TAG : 0), | ||
910 | depth_to_use); | 808 | depth_to_use); |
911 | lp->s.scdev_depth = depth_to_use; | 809 | lp->s.scdev_depth = depth_to_use; |
912 | sym_tune_dev_queuing(tp, sdev->lun, reqtags); | 810 | sym_tune_dev_queuing(tp, sdev->lun, reqtags); |
@@ -1089,8 +987,9 @@ static int is_keyword(char *ptr, int len, char *verb) | |||
1089 | * Parse a control command | 987 | * Parse a control command |
1090 | */ | 988 | */ |
1091 | 989 | ||
1092 | static int sym_user_command(struct sym_hcb *np, char *buffer, int length) | 990 | static int sym_user_command(struct Scsi_Host *shost, char *buffer, int length) |
1093 | { | 991 | { |
992 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1094 | char *ptr = buffer; | 993 | char *ptr = buffer; |
1095 | int len = length; | 994 | int len = length; |
1096 | struct sym_usrcmd cmd, *uc = &cmd; | 995 | struct sym_usrcmd cmd, *uc = &cmd; |
@@ -1217,9 +1116,9 @@ printk("sym_user_command: data=%ld\n", uc->data); | |||
1217 | else { | 1116 | else { |
1218 | unsigned long flags; | 1117 | unsigned long flags; |
1219 | 1118 | ||
1220 | spin_lock_irqsave(np->s.host->host_lock, flags); | 1119 | spin_lock_irqsave(shost->host_lock, flags); |
1221 | sym_exec_user_command (np, uc); | 1120 | sym_exec_user_command(np, uc); |
1222 | spin_unlock_irqrestore(np->s.host->host_lock, flags); | 1121 | spin_unlock_irqrestore(shost->host_lock, flags); |
1223 | } | 1122 | } |
1224 | return length; | 1123 | return length; |
1225 | } | 1124 | } |
@@ -1275,8 +1174,11 @@ static int copy_info(struct info_str *info, char *fmt, ...) | |||
1275 | /* | 1174 | /* |
1276 | * Copy formatted information into the input buffer. | 1175 | * Copy formatted information into the input buffer. |
1277 | */ | 1176 | */ |
1278 | static int sym_host_info(struct sym_hcb *np, char *ptr, off_t offset, int len) | 1177 | static int sym_host_info(struct Scsi_Host *shost, char *ptr, off_t offset, int len) |
1279 | { | 1178 | { |
1179 | struct sym_data *sym_data = shost_priv(shost); | ||
1180 | struct pci_dev *pdev = sym_data->pdev; | ||
1181 | struct sym_hcb *np = sym_data->ncb; | ||
1280 | struct info_str info; | 1182 | struct info_str info; |
1281 | 1183 | ||
1282 | info.buffer = ptr; | 1184 | info.buffer = ptr; |
@@ -1285,10 +1187,10 @@ static int sym_host_info(struct sym_hcb *np, char *ptr, off_t offset, int len) | |||
1285 | info.pos = 0; | 1187 | info.pos = 0; |
1286 | 1188 | ||
1287 | copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, " | 1189 | copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, " |
1288 | "revision id 0x%x\n", | 1190 | "revision id 0x%x\n", np->s.chip_name, |
1289 | np->s.chip_name, np->device_id, np->revision_id); | 1191 | pdev->device, pdev->revision); |
1290 | copy_info(&info, "At PCI address %s, IRQ " IRQ_FMT "\n", | 1192 | copy_info(&info, "At PCI address %s, IRQ %u\n", |
1291 | pci_name(np->s.device), IRQ_PRM(np->s.irq)); | 1193 | pci_name(pdev), pdev->irq); |
1292 | copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n", | 1194 | copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n", |
1293 | (int) (np->minsync_dt ? np->minsync_dt : np->minsync), | 1195 | (int) (np->minsync_dt ? np->minsync_dt : np->minsync), |
1294 | np->maxwide ? "Wide" : "Narrow", | 1196 | np->maxwide ? "Wide" : "Narrow", |
@@ -1307,15 +1209,14 @@ static int sym_host_info(struct sym_hcb *np, char *ptr, off_t offset, int len) | |||
1307 | * - func = 0 means read (returns adapter infos) | 1209 | * - func = 0 means read (returns adapter infos) |
1308 | * - func = 1 means write (not yet merget from sym53c8xx) | 1210 | * - func = 1 means write (not yet merget from sym53c8xx) |
1309 | */ | 1211 | */ |
1310 | static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer, | 1212 | static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer, |
1311 | char **start, off_t offset, int length, int func) | 1213 | char **start, off_t offset, int length, int func) |
1312 | { | 1214 | { |
1313 | struct sym_hcb *np = sym_get_hcb(host); | ||
1314 | int retv; | 1215 | int retv; |
1315 | 1216 | ||
1316 | if (func) { | 1217 | if (func) { |
1317 | #ifdef SYM_LINUX_USER_COMMAND_SUPPORT | 1218 | #ifdef SYM_LINUX_USER_COMMAND_SUPPORT |
1318 | retv = sym_user_command(np, buffer, length); | 1219 | retv = sym_user_command(shost, buffer, length); |
1319 | #else | 1220 | #else |
1320 | retv = -EINVAL; | 1221 | retv = -EINVAL; |
1321 | #endif | 1222 | #endif |
@@ -1323,7 +1224,7 @@ static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer, | |||
1323 | if (start) | 1224 | if (start) |
1324 | *start = buffer; | 1225 | *start = buffer; |
1325 | #ifdef SYM_LINUX_USER_INFO_SUPPORT | 1226 | #ifdef SYM_LINUX_USER_INFO_SUPPORT |
1326 | retv = sym_host_info(np, buffer, offset, length); | 1227 | retv = sym_host_info(shost, buffer, offset, length); |
1327 | #else | 1228 | #else |
1328 | retv = -EINVAL; | 1229 | retv = -EINVAL; |
1329 | #endif | 1230 | #endif |
@@ -1341,8 +1242,8 @@ static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) | |||
1341 | /* | 1242 | /* |
1342 | * Free O/S specific resources. | 1243 | * Free O/S specific resources. |
1343 | */ | 1244 | */ |
1344 | if (np->s.irq) | 1245 | if (pdev->irq) |
1345 | free_irq(np->s.irq, np); | 1246 | free_irq(pdev->irq, np); |
1346 | if (np->s.ioaddr) | 1247 | if (np->s.ioaddr) |
1347 | pci_iounmap(pdev, np->s.ioaddr); | 1248 | pci_iounmap(pdev, np->s.ioaddr); |
1348 | if (np->s.ramaddr) | 1249 | if (np->s.ramaddr) |
@@ -1356,31 +1257,6 @@ static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) | |||
1356 | } | 1257 | } |
1357 | 1258 | ||
1358 | /* | 1259 | /* |
1359 | * Ask/tell the system about DMA addressing. | ||
1360 | */ | ||
1361 | static int sym_setup_bus_dma_mask(struct sym_hcb *np) | ||
1362 | { | ||
1363 | #if SYM_CONF_DMA_ADDRESSING_MODE > 0 | ||
1364 | #if SYM_CONF_DMA_ADDRESSING_MODE == 1 | ||
1365 | #define DMA_DAC_MASK DMA_40BIT_MASK | ||
1366 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 | ||
1367 | #define DMA_DAC_MASK DMA_64BIT_MASK | ||
1368 | #endif | ||
1369 | if ((np->features & FE_DAC) && | ||
1370 | !pci_set_dma_mask(np->s.device, DMA_DAC_MASK)) { | ||
1371 | np->use_dac = 1; | ||
1372 | return 0; | ||
1373 | } | ||
1374 | #endif | ||
1375 | |||
1376 | if (!pci_set_dma_mask(np->s.device, DMA_32BIT_MASK)) | ||
1377 | return 0; | ||
1378 | |||
1379 | printf_warning("%s: No suitable DMA available\n", sym_name(np)); | ||
1380 | return -1; | ||
1381 | } | ||
1382 | |||
1383 | /* | ||
1384 | * Host attach and initialisations. | 1260 | * Host attach and initialisations. |
1385 | * | 1261 | * |
1386 | * Allocate host data and ncb structure. | 1262 | * Allocate host data and ncb structure. |
@@ -1392,32 +1268,28 @@ static int sym_setup_bus_dma_mask(struct sym_hcb *np) | |||
1392 | static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | 1268 | static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, |
1393 | int unit, struct sym_device *dev) | 1269 | int unit, struct sym_device *dev) |
1394 | { | 1270 | { |
1395 | struct host_data *host_data; | 1271 | struct sym_data *sym_data; |
1396 | struct sym_hcb *np = NULL; | 1272 | struct sym_hcb *np = NULL; |
1397 | struct Scsi_Host *instance = NULL; | 1273 | struct Scsi_Host *shost; |
1398 | struct pci_dev *pdev = dev->pdev; | 1274 | struct pci_dev *pdev = dev->pdev; |
1399 | unsigned long flags; | 1275 | unsigned long flags; |
1400 | struct sym_fw *fw; | 1276 | struct sym_fw *fw; |
1401 | 1277 | ||
1402 | printk(KERN_INFO | 1278 | printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n", |
1403 | "sym%d: <%s> rev 0x%x at pci %s irq " IRQ_FMT "\n", | 1279 | unit, dev->chip.name, pdev->revision, pci_name(pdev), |
1404 | unit, dev->chip.name, dev->chip.revision_id, | 1280 | pdev->irq); |
1405 | pci_name(pdev), IRQ_PRM(pdev->irq)); | ||
1406 | 1281 | ||
1407 | /* | 1282 | /* |
1408 | * Get the firmware for this chip. | 1283 | * Get the firmware for this chip. |
1409 | */ | 1284 | */ |
1410 | fw = sym_find_firmware(&dev->chip); | 1285 | fw = sym_find_firmware(&dev->chip); |
1411 | if (!fw) | 1286 | if (!fw) |
1412 | goto attach_failed; | 1287 | return NULL; |
1413 | 1288 | ||
1414 | /* | 1289 | shost = scsi_host_alloc(tpnt, sizeof(*sym_data)); |
1415 | * Allocate host_data structure | 1290 | if (!shost) |
1416 | */ | 1291 | return NULL; |
1417 | instance = scsi_host_alloc(tpnt, sizeof(*host_data)); | 1292 | sym_data = shost_priv(shost); |
1418 | if (!instance) | ||
1419 | goto attach_failed; | ||
1420 | host_data = (struct host_data *) instance->hostdata; | ||
1421 | 1293 | ||
1422 | /* | 1294 | /* |
1423 | * Allocate immediately the host control block, | 1295 | * Allocate immediately the host control block, |
@@ -1428,22 +1300,19 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1428 | np = __sym_calloc_dma(&pdev->dev, sizeof(*np), "HCB"); | 1300 | np = __sym_calloc_dma(&pdev->dev, sizeof(*np), "HCB"); |
1429 | if (!np) | 1301 | if (!np) |
1430 | goto attach_failed; | 1302 | goto attach_failed; |
1431 | np->s.device = pdev; | ||
1432 | np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */ | 1303 | np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */ |
1433 | host_data->ncb = np; | 1304 | sym_data->ncb = np; |
1434 | np->s.host = instance; | 1305 | sym_data->pdev = pdev; |
1306 | np->s.host = shost; | ||
1435 | 1307 | ||
1436 | pci_set_drvdata(pdev, np); | 1308 | pci_set_drvdata(pdev, shost); |
1437 | 1309 | ||
1438 | /* | 1310 | /* |
1439 | * Copy some useful infos to the HCB. | 1311 | * Copy some useful infos to the HCB. |
1440 | */ | 1312 | */ |
1441 | np->hcb_ba = vtobus(np); | 1313 | np->hcb_ba = vtobus(np); |
1442 | np->verbose = sym_driver_setup.verbose; | 1314 | np->verbose = sym_driver_setup.verbose; |
1443 | np->s.device = pdev; | ||
1444 | np->s.unit = unit; | 1315 | np->s.unit = unit; |
1445 | np->device_id = dev->chip.device_id; | ||
1446 | np->revision_id = dev->chip.revision_id; | ||
1447 | np->features = dev->chip.features; | 1316 | np->features = dev->chip.features; |
1448 | np->clock_divn = dev->chip.nr_divisor; | 1317 | np->clock_divn = dev->chip.nr_divisor; |
1449 | np->maxoffs = dev->chip.offset_max; | 1318 | np->maxoffs = dev->chip.offset_max; |
@@ -1456,8 +1325,13 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1456 | strlcpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name)); | 1325 | strlcpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name)); |
1457 | sprintf(np->s.inst_name, "sym%d", np->s.unit); | 1326 | sprintf(np->s.inst_name, "sym%d", np->s.unit); |
1458 | 1327 | ||
1459 | if (sym_setup_bus_dma_mask(np)) | 1328 | if ((SYM_CONF_DMA_ADDRESSING_MODE > 0) && (np->features & FE_DAC) && |
1329 | !pci_set_dma_mask(pdev, DMA_DAC_MASK)) { | ||
1330 | set_dac(np); | ||
1331 | } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | ||
1332 | printf_warning("%s: No suitable DMA available\n", sym_name(np)); | ||
1460 | goto attach_failed; | 1333 | goto attach_failed; |
1334 | } | ||
1461 | 1335 | ||
1462 | /* | 1336 | /* |
1463 | * Try to map the controller chip to | 1337 | * Try to map the controller chip to |
@@ -1466,19 +1340,16 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1466 | np->mmio_ba = (u32)dev->mmio_base; | 1340 | np->mmio_ba = (u32)dev->mmio_base; |
1467 | np->s.ioaddr = dev->s.ioaddr; | 1341 | np->s.ioaddr = dev->s.ioaddr; |
1468 | np->s.ramaddr = dev->s.ramaddr; | 1342 | np->s.ramaddr = dev->s.ramaddr; |
1469 | np->s.io_ws = (np->features & FE_IO256) ? 256 : 128; | ||
1470 | 1343 | ||
1471 | /* | 1344 | /* |
1472 | * Map on-chip RAM if present and supported. | 1345 | * Map on-chip RAM if present and supported. |
1473 | */ | 1346 | */ |
1474 | if (!(np->features & FE_RAM)) | 1347 | if (!(np->features & FE_RAM)) |
1475 | dev->ram_base = 0; | 1348 | dev->ram_base = 0; |
1476 | if (dev->ram_base) { | 1349 | if (dev->ram_base) |
1477 | np->ram_ba = (u32)dev->ram_base; | 1350 | np->ram_ba = (u32)dev->ram_base; |
1478 | np->ram_ws = (np->features & FE_RAM8K) ? 8192 : 4096; | ||
1479 | } | ||
1480 | 1351 | ||
1481 | if (sym_hcb_attach(instance, fw, dev->nvram)) | 1352 | if (sym_hcb_attach(shost, fw, dev->nvram)) |
1482 | goto attach_failed; | 1353 | goto attach_failed; |
1483 | 1354 | ||
1484 | /* | 1355 | /* |
@@ -1486,25 +1357,25 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1486 | * If we synchonize the C code with SCRIPTS on interrupt, | 1357 | * If we synchonize the C code with SCRIPTS on interrupt, |
1487 | * we do not want to share the INTR line at all. | 1358 | * we do not want to share the INTR line at all. |
1488 | */ | 1359 | */ |
1489 | if (request_irq(pdev->irq, sym53c8xx_intr, IRQF_SHARED, NAME53C8XX, np)) { | 1360 | if (request_irq(pdev->irq, sym53c8xx_intr, IRQF_SHARED, NAME53C8XX, |
1490 | printf_err("%s: request irq %d failure\n", | 1361 | shost)) { |
1362 | printf_err("%s: request irq %u failure\n", | ||
1491 | sym_name(np), pdev->irq); | 1363 | sym_name(np), pdev->irq); |
1492 | goto attach_failed; | 1364 | goto attach_failed; |
1493 | } | 1365 | } |
1494 | np->s.irq = pdev->irq; | ||
1495 | 1366 | ||
1496 | /* | 1367 | /* |
1497 | * After SCSI devices have been opened, we cannot | 1368 | * After SCSI devices have been opened, we cannot |
1498 | * reset the bus safely, so we do it here. | 1369 | * reset the bus safely, so we do it here. |
1499 | */ | 1370 | */ |
1500 | spin_lock_irqsave(instance->host_lock, flags); | 1371 | spin_lock_irqsave(shost->host_lock, flags); |
1501 | if (sym_reset_scsi_bus(np, 0)) | 1372 | if (sym_reset_scsi_bus(np, 0)) |
1502 | goto reset_failed; | 1373 | goto reset_failed; |
1503 | 1374 | ||
1504 | /* | 1375 | /* |
1505 | * Start the SCRIPTS. | 1376 | * Start the SCRIPTS. |
1506 | */ | 1377 | */ |
1507 | sym_start_up (np, 1); | 1378 | sym_start_up(shost, 1); |
1508 | 1379 | ||
1509 | /* | 1380 | /* |
1510 | * Start the timer daemon | 1381 | * Start the timer daemon |
@@ -1519,33 +1390,37 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1519 | * Fill Linux host instance structure | 1390 | * Fill Linux host instance structure |
1520 | * and return success. | 1391 | * and return success. |
1521 | */ | 1392 | */ |
1522 | instance->max_channel = 0; | 1393 | shost->max_channel = 0; |
1523 | instance->this_id = np->myaddr; | 1394 | shost->this_id = np->myaddr; |
1524 | instance->max_id = np->maxwide ? 16 : 8; | 1395 | shost->max_id = np->maxwide ? 16 : 8; |
1525 | instance->max_lun = SYM_CONF_MAX_LUN; | 1396 | shost->max_lun = SYM_CONF_MAX_LUN; |
1526 | instance->unique_id = pci_resource_start(pdev, 0); | 1397 | shost->unique_id = pci_resource_start(pdev, 0); |
1527 | instance->cmd_per_lun = SYM_CONF_MAX_TAG; | 1398 | shost->cmd_per_lun = SYM_CONF_MAX_TAG; |
1528 | instance->can_queue = (SYM_CONF_MAX_START-2); | 1399 | shost->can_queue = (SYM_CONF_MAX_START-2); |
1529 | instance->sg_tablesize = SYM_CONF_MAX_SG; | 1400 | shost->sg_tablesize = SYM_CONF_MAX_SG; |
1530 | instance->max_cmd_len = 16; | 1401 | shost->max_cmd_len = 16; |
1531 | BUG_ON(sym2_transport_template == NULL); | 1402 | BUG_ON(sym2_transport_template == NULL); |
1532 | instance->transportt = sym2_transport_template; | 1403 | shost->transportt = sym2_transport_template; |
1404 | |||
1405 | /* 53c896 rev 1 errata: DMA may not cross 16MB boundary */ | ||
1406 | if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 2) | ||
1407 | shost->dma_boundary = 0xFFFFFF; | ||
1533 | 1408 | ||
1534 | spin_unlock_irqrestore(instance->host_lock, flags); | 1409 | spin_unlock_irqrestore(shost->host_lock, flags); |
1535 | 1410 | ||
1536 | return instance; | 1411 | return shost; |
1537 | 1412 | ||
1538 | reset_failed: | 1413 | reset_failed: |
1539 | printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, " | 1414 | printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, " |
1540 | "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); | 1415 | "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); |
1541 | spin_unlock_irqrestore(instance->host_lock, flags); | 1416 | spin_unlock_irqrestore(shost->host_lock, flags); |
1542 | attach_failed: | 1417 | attach_failed: |
1543 | if (!instance) | 1418 | if (!shost) |
1544 | return NULL; | 1419 | return NULL; |
1545 | printf_info("%s: giving up ...\n", sym_name(np)); | 1420 | printf_info("%s: giving up ...\n", sym_name(np)); |
1546 | if (np) | 1421 | if (np) |
1547 | sym_free_resources(np, pdev); | 1422 | sym_free_resources(np, pdev); |
1548 | scsi_host_put(instance); | 1423 | scsi_host_put(shost); |
1549 | 1424 | ||
1550 | return NULL; | 1425 | return NULL; |
1551 | } | 1426 | } |
@@ -1558,7 +1433,6 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1558 | static void __devinit sym_get_nvram(struct sym_device *devp, struct sym_nvram *nvp) | 1433 | static void __devinit sym_get_nvram(struct sym_device *devp, struct sym_nvram *nvp) |
1559 | { | 1434 | { |
1560 | devp->nvram = nvp; | 1435 | devp->nvram = nvp; |
1561 | devp->device_id = devp->chip.device_id; | ||
1562 | nvp->type = 0; | 1436 | nvp->type = 0; |
1563 | 1437 | ||
1564 | sym_read_nvram(devp, nvp); | 1438 | sym_read_nvram(devp, nvp); |
@@ -1573,7 +1447,6 @@ static int __devinit sym_check_supported(struct sym_device *device) | |||
1573 | { | 1447 | { |
1574 | struct sym_chip *chip; | 1448 | struct sym_chip *chip; |
1575 | struct pci_dev *pdev = device->pdev; | 1449 | struct pci_dev *pdev = device->pdev; |
1576 | u_char revision; | ||
1577 | unsigned long io_port = pci_resource_start(pdev, 0); | 1450 | unsigned long io_port = pci_resource_start(pdev, 0); |
1578 | int i; | 1451 | int i; |
1579 | 1452 | ||
@@ -1593,14 +1466,12 @@ static int __devinit sym_check_supported(struct sym_device *device) | |||
1593 | * to our device structure so we can make it match the actual device | 1466 | * to our device structure so we can make it match the actual device |
1594 | * and options. | 1467 | * and options. |
1595 | */ | 1468 | */ |
1596 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); | 1469 | chip = sym_lookup_chip_table(pdev->device, pdev->revision); |
1597 | chip = sym_lookup_chip_table(pdev->device, revision); | ||
1598 | if (!chip) { | 1470 | if (!chip) { |
1599 | dev_info(&pdev->dev, "device not supported\n"); | 1471 | dev_info(&pdev->dev, "device not supported\n"); |
1600 | return -ENODEV; | 1472 | return -ENODEV; |
1601 | } | 1473 | } |
1602 | memcpy(&device->chip, chip, sizeof(device->chip)); | 1474 | memcpy(&device->chip, chip, sizeof(device->chip)); |
1603 | device->chip.revision_id = revision; | ||
1604 | 1475 | ||
1605 | return 0; | 1476 | return 0; |
1606 | } | 1477 | } |
@@ -1641,7 +1512,7 @@ static int __devinit sym_set_workarounds(struct sym_device *device) | |||
1641 | * We must ensure the chip will use WRITE AND INVALIDATE. | 1512 | * We must ensure the chip will use WRITE AND INVALIDATE. |
1642 | * The revision number limit is for now arbitrary. | 1513 | * The revision number limit is for now arbitrary. |
1643 | */ | 1514 | */ |
1644 | if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && chip->revision_id < 0x4) { | 1515 | if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 0x4) { |
1645 | chip->features |= (FE_WRIE | FE_CLSE); | 1516 | chip->features |= (FE_WRIE | FE_CLSE); |
1646 | } | 1517 | } |
1647 | 1518 | ||
@@ -1769,8 +1640,9 @@ static void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev) | |||
1769 | * Detach the host. | 1640 | * Detach the host. |
1770 | * We have to free resources and halt the NCR chip. | 1641 | * We have to free resources and halt the NCR chip. |
1771 | */ | 1642 | */ |
1772 | static int sym_detach(struct sym_hcb *np, struct pci_dev *pdev) | 1643 | static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev) |
1773 | { | 1644 | { |
1645 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1774 | printk("%s: detaching ...\n", sym_name(np)); | 1646 | printk("%s: detaching ...\n", sym_name(np)); |
1775 | 1647 | ||
1776 | del_timer_sync(&np->s.timer); | 1648 | del_timer_sync(&np->s.timer); |
@@ -1823,7 +1695,7 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1823 | { | 1695 | { |
1824 | struct sym_device sym_dev; | 1696 | struct sym_device sym_dev; |
1825 | struct sym_nvram nvram; | 1697 | struct sym_nvram nvram; |
1826 | struct Scsi_Host *instance; | 1698 | struct Scsi_Host *shost; |
1827 | 1699 | ||
1828 | memset(&sym_dev, 0, sizeof(sym_dev)); | 1700 | memset(&sym_dev, 0, sizeof(sym_dev)); |
1829 | memset(&nvram, 0, sizeof(nvram)); | 1701 | memset(&nvram, 0, sizeof(nvram)); |
@@ -1850,13 +1722,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1850 | 1722 | ||
1851 | sym_get_nvram(&sym_dev, &nvram); | 1723 | sym_get_nvram(&sym_dev, &nvram); |
1852 | 1724 | ||
1853 | instance = sym_attach(&sym2_template, attach_count, &sym_dev); | 1725 | shost = sym_attach(&sym2_template, attach_count, &sym_dev); |
1854 | if (!instance) | 1726 | if (!shost) |
1855 | goto free; | 1727 | goto free; |
1856 | 1728 | ||
1857 | if (scsi_add_host(instance, &pdev->dev)) | 1729 | if (scsi_add_host(shost, &pdev->dev)) |
1858 | goto detach; | 1730 | goto detach; |
1859 | scsi_scan_host(instance); | 1731 | scsi_scan_host(shost); |
1860 | 1732 | ||
1861 | attach_count++; | 1733 | attach_count++; |
1862 | 1734 | ||
@@ -1874,20 +1746,143 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1874 | 1746 | ||
1875 | static void __devexit sym2_remove(struct pci_dev *pdev) | 1747 | static void __devexit sym2_remove(struct pci_dev *pdev) |
1876 | { | 1748 | { |
1877 | struct sym_hcb *np = pci_get_drvdata(pdev); | 1749 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
1878 | struct Scsi_Host *host = np->s.host; | ||
1879 | |||
1880 | scsi_remove_host(host); | ||
1881 | scsi_host_put(host); | ||
1882 | |||
1883 | sym_detach(np, pdev); | ||
1884 | 1750 | ||
1751 | scsi_remove_host(shost); | ||
1752 | scsi_host_put(shost); | ||
1753 | sym_detach(shost, pdev); | ||
1885 | pci_release_regions(pdev); | 1754 | pci_release_regions(pdev); |
1886 | pci_disable_device(pdev); | 1755 | pci_disable_device(pdev); |
1887 | 1756 | ||
1888 | attach_count--; | 1757 | attach_count--; |
1889 | } | 1758 | } |
1890 | 1759 | ||
1760 | /** | ||
1761 | * sym2_io_error_detected() - called when PCI error is detected | ||
1762 | * @pdev: pointer to PCI device | ||
1763 | * @state: current state of the PCI slot | ||
1764 | */ | ||
1765 | static pci_ers_result_t sym2_io_error_detected(struct pci_dev *pdev, | ||
1766 | enum pci_channel_state state) | ||
1767 | { | ||
1768 | /* If slot is permanently frozen, turn everything off */ | ||
1769 | if (state == pci_channel_io_perm_failure) { | ||
1770 | sym2_remove(pdev); | ||
1771 | return PCI_ERS_RESULT_DISCONNECT; | ||
1772 | } | ||
1773 | |||
1774 | disable_irq(pdev->irq); | ||
1775 | pci_disable_device(pdev); | ||
1776 | |||
1777 | /* Request that MMIO be enabled, so register dump can be taken. */ | ||
1778 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
1779 | } | ||
1780 | |||
1781 | /** | ||
1782 | * sym2_io_slot_dump - Enable MMIO and dump debug registers | ||
1783 | * @pdev: pointer to PCI device | ||
1784 | */ | ||
1785 | static pci_ers_result_t sym2_io_slot_dump(struct pci_dev *pdev) | ||
1786 | { | ||
1787 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1788 | |||
1789 | sym_dump_registers(shost); | ||
1790 | |||
1791 | /* Request a slot reset. */ | ||
1792 | return PCI_ERS_RESULT_NEED_RESET; | ||
1793 | } | ||
1794 | |||
1795 | /** | ||
1796 | * sym2_reset_workarounds - hardware-specific work-arounds | ||
1797 | * | ||
1798 | * This routine is similar to sym_set_workarounds(), except | ||
1799 | * that, at this point, we already know that the device was | ||
1800 | * succesfully intialized at least once before, and so most | ||
1801 | * of the steps taken there are un-needed here. | ||
1802 | */ | ||
1803 | static void sym2_reset_workarounds(struct pci_dev *pdev) | ||
1804 | { | ||
1805 | u_short status_reg; | ||
1806 | struct sym_chip *chip; | ||
1807 | |||
1808 | chip = sym_lookup_chip_table(pdev->device, pdev->revision); | ||
1809 | |||
1810 | /* Work around for errant bit in 895A, in a fashion | ||
1811 | * similar to what is done in sym_set_workarounds(). | ||
1812 | */ | ||
1813 | pci_read_config_word(pdev, PCI_STATUS, &status_reg); | ||
1814 | if (!(chip->features & FE_66MHZ) && (status_reg & PCI_STATUS_66MHZ)) { | ||
1815 | status_reg = PCI_STATUS_66MHZ; | ||
1816 | pci_write_config_word(pdev, PCI_STATUS, status_reg); | ||
1817 | pci_read_config_word(pdev, PCI_STATUS, &status_reg); | ||
1818 | } | ||
1819 | } | ||
1820 | |||
1821 | /** | ||
1822 | * sym2_io_slot_reset() - called when the pci bus has been reset. | ||
1823 | * @pdev: pointer to PCI device | ||
1824 | * | ||
1825 | * Restart the card from scratch. | ||
1826 | */ | ||
1827 | static pci_ers_result_t sym2_io_slot_reset(struct pci_dev *pdev) | ||
1828 | { | ||
1829 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1830 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1831 | |||
1832 | printk(KERN_INFO "%s: recovering from a PCI slot reset\n", | ||
1833 | sym_name(np)); | ||
1834 | |||
1835 | if (pci_enable_device(pdev)) { | ||
1836 | printk(KERN_ERR "%s: Unable to enable after PCI reset\n", | ||
1837 | sym_name(np)); | ||
1838 | return PCI_ERS_RESULT_DISCONNECT; | ||
1839 | } | ||
1840 | |||
1841 | pci_set_master(pdev); | ||
1842 | enable_irq(pdev->irq); | ||
1843 | |||
1844 | /* If the chip can do Memory Write Invalidate, enable it */ | ||
1845 | if (np->features & FE_WRIE) { | ||
1846 | if (pci_set_mwi(pdev)) | ||
1847 | return PCI_ERS_RESULT_DISCONNECT; | ||
1848 | } | ||
1849 | |||
1850 | /* Perform work-arounds, analogous to sym_set_workarounds() */ | ||
1851 | sym2_reset_workarounds(pdev); | ||
1852 | |||
1853 | /* Perform host reset only on one instance of the card */ | ||
1854 | if (PCI_FUNC(pdev->devfn) == 0) { | ||
1855 | if (sym_reset_scsi_bus(np, 0)) { | ||
1856 | printk(KERN_ERR "%s: Unable to reset scsi host\n", | ||
1857 | sym_name(np)); | ||
1858 | return PCI_ERS_RESULT_DISCONNECT; | ||
1859 | } | ||
1860 | sym_start_up(shost, 1); | ||
1861 | } | ||
1862 | |||
1863 | return PCI_ERS_RESULT_RECOVERED; | ||
1864 | } | ||
1865 | |||
1866 | /** | ||
1867 | * sym2_io_resume() - resume normal ops after PCI reset | ||
1868 | * @pdev: pointer to PCI device | ||
1869 | * | ||
1870 | * Called when the error recovery driver tells us that its | ||
1871 | * OK to resume normal operation. Use completion to allow | ||
1872 | * halted scsi ops to resume. | ||
1873 | */ | ||
1874 | static void sym2_io_resume(struct pci_dev *pdev) | ||
1875 | { | ||
1876 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1877 | struct sym_data *sym_data = shost_priv(shost); | ||
1878 | |||
1879 | spin_lock_irq(shost->host_lock); | ||
1880 | if (sym_data->io_reset) | ||
1881 | complete_all(sym_data->io_reset); | ||
1882 | sym_data->io_reset = NULL; | ||
1883 | spin_unlock_irq(shost->host_lock); | ||
1884 | } | ||
1885 | |||
1891 | static void sym2_get_signalling(struct Scsi_Host *shost) | 1886 | static void sym2_get_signalling(struct Scsi_Host *shost) |
1892 | { | 1887 | { |
1893 | struct sym_hcb *np = sym_get_hcb(shost); | 1888 | struct sym_hcb *np = sym_get_hcb(shost); |
@@ -2050,11 +2045,19 @@ static struct pci_device_id sym2_id_table[] __devinitdata = { | |||
2050 | 2045 | ||
2051 | MODULE_DEVICE_TABLE(pci, sym2_id_table); | 2046 | MODULE_DEVICE_TABLE(pci, sym2_id_table); |
2052 | 2047 | ||
2048 | static struct pci_error_handlers sym2_err_handler = { | ||
2049 | .error_detected = sym2_io_error_detected, | ||
2050 | .mmio_enabled = sym2_io_slot_dump, | ||
2051 | .slot_reset = sym2_io_slot_reset, | ||
2052 | .resume = sym2_io_resume, | ||
2053 | }; | ||
2054 | |||
2053 | static struct pci_driver sym2_driver = { | 2055 | static struct pci_driver sym2_driver = { |
2054 | .name = NAME53C8XX, | 2056 | .name = NAME53C8XX, |
2055 | .id_table = sym2_id_table, | 2057 | .id_table = sym2_id_table, |
2056 | .probe = sym2_probe, | 2058 | .probe = sym2_probe, |
2057 | .remove = __devexit_p(sym2_remove), | 2059 | .remove = __devexit_p(sym2_remove), |
2060 | .err_handler = &sym2_err_handler, | ||
2058 | }; | 2061 | }; |
2059 | 2062 | ||
2060 | static int __init sym2_init(void) | 2063 | static int __init sym2_init(void) |
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h index 0f097ba4f712..567fbe0b4f09 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.h +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h | |||
@@ -40,7 +40,9 @@ | |||
40 | #ifndef SYM_GLUE_H | 40 | #ifndef SYM_GLUE_H |
41 | #define SYM_GLUE_H | 41 | #define SYM_GLUE_H |
42 | 42 | ||
43 | #include <linux/completion.h> | ||
43 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
45 | #include <linux/interrupt.h> | ||
44 | #include <linux/ioport.h> | 46 | #include <linux/ioport.h> |
45 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
46 | #include <linux/string.h> | 48 | #include <linux/string.h> |
@@ -177,14 +179,11 @@ struct sym_shcb { | |||
177 | int unit; | 179 | int unit; |
178 | char inst_name[16]; | 180 | char inst_name[16]; |
179 | char chip_name[8]; | 181 | char chip_name[8]; |
180 | struct pci_dev *device; | ||
181 | 182 | ||
182 | struct Scsi_Host *host; | 183 | struct Scsi_Host *host; |
183 | 184 | ||
184 | void __iomem * ioaddr; /* MMIO kernel io address */ | 185 | void __iomem * ioaddr; /* MMIO kernel io address */ |
185 | void __iomem * ramaddr; /* RAM kernel io address */ | 186 | void __iomem * ramaddr; /* RAM kernel io address */ |
186 | u_short io_ws; /* IO window size */ | ||
187 | int irq; /* IRQ number */ | ||
188 | 187 | ||
189 | struct timer_list timer; /* Timer handler link header */ | 188 | struct timer_list timer; /* Timer handler link header */ |
190 | u_long lasttime; | 189 | u_long lasttime; |
@@ -212,20 +211,21 @@ struct sym_device { | |||
212 | } s; | 211 | } s; |
213 | struct sym_chip chip; | 212 | struct sym_chip chip; |
214 | struct sym_nvram *nvram; | 213 | struct sym_nvram *nvram; |
215 | u_short device_id; | ||
216 | u_char host_id; | 214 | u_char host_id; |
217 | }; | 215 | }; |
218 | 216 | ||
219 | /* | 217 | /* |
220 | * Driver host data structure. | 218 | * Driver host data structure. |
221 | */ | 219 | */ |
222 | struct host_data { | 220 | struct sym_data { |
223 | struct sym_hcb *ncb; | 221 | struct sym_hcb *ncb; |
222 | struct completion *io_reset; /* PCI error handling */ | ||
223 | struct pci_dev *pdev; | ||
224 | }; | 224 | }; |
225 | 225 | ||
226 | static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) | 226 | static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) |
227 | { | 227 | { |
228 | return ((struct host_data *)host->hostdata)->ncb; | 228 | return ((struct sym_data *)host->hostdata)->ncb; |
229 | } | 229 | } |
230 | 230 | ||
231 | #include "sym_fw.h" | 231 | #include "sym_fw.h" |
@@ -263,8 +263,8 @@ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid) | |||
263 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb); | 263 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb); |
264 | #define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg) | 264 | #define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg) |
265 | void sym_xpt_async_bus_reset(struct sym_hcb *np); | 265 | void sym_xpt_async_bus_reset(struct sym_hcb *np); |
266 | void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target); | ||
267 | int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); | 266 | int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); |
268 | void sym_log_bus_error(struct sym_hcb *np); | 267 | void sym_log_bus_error(struct Scsi_Host *); |
268 | void sym_dump_registers(struct Scsi_Host *); | ||
269 | 269 | ||
270 | #endif /* SYM_GLUE_H */ | 270 | #endif /* SYM_GLUE_H */ |
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 21cd4c7f5289..463f119f20e9 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c | |||
@@ -52,7 +52,7 @@ | |||
52 | * Needed function prototypes. | 52 | * Needed function prototypes. |
53 | */ | 53 | */ |
54 | static void sym_int_ma (struct sym_hcb *np); | 54 | static void sym_int_ma (struct sym_hcb *np); |
55 | static void sym_int_sir (struct sym_hcb *np); | 55 | static void sym_int_sir(struct sym_hcb *); |
56 | static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np); | 56 | static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np); |
57 | static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa); | 57 | static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa); |
58 | static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln); | 58 | static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln); |
@@ -684,6 +684,8 @@ static void sym_set_bus_mode(struct sym_hcb *np, struct sym_nvram *nvram) | |||
684 | */ | 684 | */ |
685 | static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) | 685 | static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) |
686 | { | 686 | { |
687 | struct sym_data *sym_data = shost_priv(shost); | ||
688 | struct pci_dev *pdev = sym_data->pdev; | ||
687 | u_char burst_max; | 689 | u_char burst_max; |
688 | u32 period; | 690 | u32 period; |
689 | int i; | 691 | int i; |
@@ -778,19 +780,12 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
778 | * 64 bit addressing (895A/896/1010) ? | 780 | * 64 bit addressing (895A/896/1010) ? |
779 | */ | 781 | */ |
780 | if (np->features & FE_DAC) { | 782 | if (np->features & FE_DAC) { |
781 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 | 783 | if (!use_dac(np)) |
782 | np->rv_ccntl1 |= (DDAC); | 784 | np->rv_ccntl1 |= (DDAC); |
783 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 1 | 785 | else if (SYM_CONF_DMA_ADDRESSING_MODE == 1) |
784 | if (!np->use_dac) | 786 | np->rv_ccntl1 |= (XTIMOD | EXTIBMV); |
785 | np->rv_ccntl1 |= (DDAC); | 787 | else if (SYM_CONF_DMA_ADDRESSING_MODE == 2) |
786 | else | 788 | np->rv_ccntl1 |= (0 | EXTIBMV); |
787 | np->rv_ccntl1 |= (XTIMOD | EXTIBMV); | ||
788 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 | ||
789 | if (!np->use_dac) | ||
790 | np->rv_ccntl1 |= (DDAC); | ||
791 | else | ||
792 | np->rv_ccntl1 |= (0 | EXTIBMV); | ||
793 | #endif | ||
794 | } | 789 | } |
795 | 790 | ||
796 | /* | 791 | /* |
@@ -804,8 +799,8 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
804 | * In dual channel mode, contention occurs if internal cycles | 799 | * In dual channel mode, contention occurs if internal cycles |
805 | * are used. Disable internal cycles. | 800 | * are used. Disable internal cycles. |
806 | */ | 801 | */ |
807 | if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && | 802 | if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 && |
808 | np->revision_id < 0x1) | 803 | pdev->revision < 0x1) |
809 | np->rv_ccntl0 |= DILS; | 804 | np->rv_ccntl0 |= DILS; |
810 | 805 | ||
811 | /* | 806 | /* |
@@ -828,10 +823,10 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
828 | * this driver. The generic ncr driver that does not use | 823 | * this driver. The generic ncr driver that does not use |
829 | * LOAD/STORE instructions does not need this work-around. | 824 | * LOAD/STORE instructions does not need this work-around. |
830 | */ | 825 | */ |
831 | if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 && | 826 | if ((pdev->device == PCI_DEVICE_ID_NCR_53C810 && |
832 | np->revision_id >= 0x10 && np->revision_id <= 0x11) || | 827 | pdev->revision >= 0x10 && pdev->revision <= 0x11) || |
833 | (np->device_id == PCI_DEVICE_ID_NCR_53C860 && | 828 | (pdev->device == PCI_DEVICE_ID_NCR_53C860 && |
834 | np->revision_id <= 0x1)) | 829 | pdev->revision <= 0x1)) |
835 | np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP); | 830 | np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP); |
836 | 831 | ||
837 | /* | 832 | /* |
@@ -897,7 +892,7 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
897 | if ((SYM_SETUP_SCSI_LED || | 892 | if ((SYM_SETUP_SCSI_LED || |
898 | (nvram->type == SYM_SYMBIOS_NVRAM || | 893 | (nvram->type == SYM_SYMBIOS_NVRAM || |
899 | (nvram->type == SYM_TEKRAM_NVRAM && | 894 | (nvram->type == SYM_TEKRAM_NVRAM && |
900 | np->device_id == PCI_DEVICE_ID_NCR_53C895))) && | 895 | pdev->device == PCI_DEVICE_ID_NCR_53C895))) && |
901 | !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01)) | 896 | !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01)) |
902 | np->features |= FE_LED0; | 897 | np->features |= FE_LED0; |
903 | 898 | ||
@@ -1135,8 +1130,9 @@ restart_test: | |||
1135 | * First 24 register of the chip: | 1130 | * First 24 register of the chip: |
1136 | * r0..rf | 1131 | * r0..rf |
1137 | */ | 1132 | */ |
1138 | static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat) | 1133 | static void sym_log_hard_error(struct Scsi_Host *shost, u_short sist, u_char dstat) |
1139 | { | 1134 | { |
1135 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1140 | u32 dsp; | 1136 | u32 dsp; |
1141 | int script_ofs; | 1137 | int script_ofs; |
1142 | int script_size; | 1138 | int script_size; |
@@ -1180,16 +1176,27 @@ static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat) | |||
1180 | scr_to_cpu((int) *(u32 *)(script_base + script_ofs))); | 1176 | scr_to_cpu((int) *(u32 *)(script_base + script_ofs))); |
1181 | } | 1177 | } |
1182 | 1178 | ||
1183 | printf ("%s: regdump:", sym_name(np)); | 1179 | printf("%s: regdump:", sym_name(np)); |
1184 | for (i=0; i<24;i++) | 1180 | for (i = 0; i < 24; i++) |
1185 | printf (" %02x", (unsigned)INB_OFF(np, i)); | 1181 | printf(" %02x", (unsigned)INB_OFF(np, i)); |
1186 | printf (".\n"); | 1182 | printf(".\n"); |
1187 | 1183 | ||
1188 | /* | 1184 | /* |
1189 | * PCI BUS error. | 1185 | * PCI BUS error. |
1190 | */ | 1186 | */ |
1191 | if (dstat & (MDPE|BF)) | 1187 | if (dstat & (MDPE|BF)) |
1192 | sym_log_bus_error(np); | 1188 | sym_log_bus_error(shost); |
1189 | } | ||
1190 | |||
1191 | void sym_dump_registers(struct Scsi_Host *shost) | ||
1192 | { | ||
1193 | struct sym_hcb *np = sym_get_hcb(shost); | ||
1194 | u_short sist; | ||
1195 | u_char dstat; | ||
1196 | |||
1197 | sist = INW(np, nc_sist); | ||
1198 | dstat = INB(np, nc_dstat); | ||
1199 | sym_log_hard_error(shost, sist, dstat); | ||
1193 | } | 1200 | } |
1194 | 1201 | ||
1195 | static struct sym_chip sym_dev_table[] = { | 1202 | static struct sym_chip sym_dev_table[] = { |
@@ -1312,7 +1319,7 @@ int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s) | |||
1312 | { | 1319 | { |
1313 | int i; | 1320 | int i; |
1314 | 1321 | ||
1315 | if (!np->use_dac) | 1322 | if (!use_dac(np)) |
1316 | goto weird; | 1323 | goto weird; |
1317 | 1324 | ||
1318 | /* Look up existing mappings */ | 1325 | /* Look up existing mappings */ |
@@ -1519,7 +1526,8 @@ void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp) | |||
1519 | np->squeueput = qidx; | 1526 | np->squeueput = qidx; |
1520 | 1527 | ||
1521 | if (DEBUG_FLAGS & DEBUG_QUEUE) | 1528 | if (DEBUG_FLAGS & DEBUG_QUEUE) |
1522 | printf ("%s: queuepos=%d.\n", sym_name (np), np->squeueput); | 1529 | scmd_printk(KERN_DEBUG, cp->cmd, "queuepos=%d\n", |
1530 | np->squeueput); | ||
1523 | 1531 | ||
1524 | /* | 1532 | /* |
1525 | * Script processor may be waiting for reselect. | 1533 | * Script processor may be waiting for reselect. |
@@ -1696,8 +1704,11 @@ static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status) | |||
1696 | * 1: SCSI BUS RESET delivered or received. | 1704 | * 1: SCSI BUS RESET delivered or received. |
1697 | * 2: SCSI BUS MODE changed. | 1705 | * 2: SCSI BUS MODE changed. |
1698 | */ | 1706 | */ |
1699 | void sym_start_up (struct sym_hcb *np, int reason) | 1707 | void sym_start_up(struct Scsi_Host *shost, int reason) |
1700 | { | 1708 | { |
1709 | struct sym_data *sym_data = shost_priv(shost); | ||
1710 | struct pci_dev *pdev = sym_data->pdev; | ||
1711 | struct sym_hcb *np = sym_data->ncb; | ||
1701 | int i; | 1712 | int i; |
1702 | u32 phys; | 1713 | u32 phys; |
1703 | 1714 | ||
@@ -1746,7 +1757,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1746 | * This also let point to first position the start | 1757 | * This also let point to first position the start |
1747 | * and done queue pointers used from SCRIPTS. | 1758 | * and done queue pointers used from SCRIPTS. |
1748 | */ | 1759 | */ |
1749 | np->fw_patch(np); | 1760 | np->fw_patch(shost); |
1750 | 1761 | ||
1751 | /* | 1762 | /* |
1752 | * Wakeup all pending jobs. | 1763 | * Wakeup all pending jobs. |
@@ -1788,7 +1799,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1788 | /* | 1799 | /* |
1789 | * For now, disable AIP generation on C1010-66. | 1800 | * For now, disable AIP generation on C1010-66. |
1790 | */ | 1801 | */ |
1791 | if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66) | 1802 | if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_66) |
1792 | OUTB(np, nc_aipcntl1, DISAIP); | 1803 | OUTB(np, nc_aipcntl1, DISAIP); |
1793 | 1804 | ||
1794 | /* | 1805 | /* |
@@ -1798,8 +1809,8 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1798 | * that from SCRIPTS for each selection/reselection, but | 1809 | * that from SCRIPTS for each selection/reselection, but |
1799 | * I just don't want. :) | 1810 | * I just don't want. :) |
1800 | */ | 1811 | */ |
1801 | if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && | 1812 | if (pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 && |
1802 | np->revision_id < 1) | 1813 | pdev->revision < 1) |
1803 | OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30); | 1814 | OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30); |
1804 | 1815 | ||
1805 | /* | 1816 | /* |
@@ -1807,9 +1818,9 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1807 | * Disable overlapped arbitration for some dual function devices, | 1818 | * Disable overlapped arbitration for some dual function devices, |
1808 | * regardless revision id (kind of post-chip-design feature. ;-)) | 1819 | * regardless revision id (kind of post-chip-design feature. ;-)) |
1809 | */ | 1820 | */ |
1810 | if (np->device_id == PCI_DEVICE_ID_NCR_53C875) | 1821 | if (pdev->device == PCI_DEVICE_ID_NCR_53C875) |
1811 | OUTB(np, nc_ctest0, (1<<5)); | 1822 | OUTB(np, nc_ctest0, (1<<5)); |
1812 | else if (np->device_id == PCI_DEVICE_ID_NCR_53C896) | 1823 | else if (pdev->device == PCI_DEVICE_ID_NCR_53C896) |
1813 | np->rv_ccntl0 |= DPR; | 1824 | np->rv_ccntl0 |= DPR; |
1814 | 1825 | ||
1815 | /* | 1826 | /* |
@@ -1827,7 +1838,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1827 | * Set up scratch C and DRS IO registers to map the 32 bit | 1838 | * Set up scratch C and DRS IO registers to map the 32 bit |
1828 | * DMA address range our data structures are located in. | 1839 | * DMA address range our data structures are located in. |
1829 | */ | 1840 | */ |
1830 | if (np->use_dac) { | 1841 | if (use_dac(np)) { |
1831 | np->dmap_bah[0] = 0; /* ??? */ | 1842 | np->dmap_bah[0] = 0; /* ??? */ |
1832 | OUTL(np, nc_scrx[0], np->dmap_bah[0]); | 1843 | OUTL(np, nc_scrx[0], np->dmap_bah[0]); |
1833 | OUTL(np, nc_drs, np->dmap_bah[0]); | 1844 | OUTL(np, nc_drs, np->dmap_bah[0]); |
@@ -1900,7 +1911,7 @@ void sym_start_up (struct sym_hcb *np, int reason) | |||
1900 | if (sym_verbose >= 2) | 1911 | if (sym_verbose >= 2) |
1901 | printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np)); | 1912 | printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np)); |
1902 | memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz); | 1913 | memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz); |
1903 | if (np->ram_ws == 8192) { | 1914 | if (np->features & FE_RAM8K) { |
1904 | memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz); | 1915 | memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz); |
1905 | phys = scr_to_cpu(np->scr_ram_seg); | 1916 | phys = scr_to_cpu(np->scr_ram_seg); |
1906 | OUTL(np, nc_mmws, phys); | 1917 | OUTL(np, nc_mmws, phys); |
@@ -2214,8 +2225,9 @@ static void sym_int_udc (struct sym_hcb *np) | |||
2214 | * mode to eight bit asynchronous, etc... | 2225 | * mode to eight bit asynchronous, etc... |
2215 | * So, just reinitializing all except chip should be enough. | 2226 | * So, just reinitializing all except chip should be enough. |
2216 | */ | 2227 | */ |
2217 | static void sym_int_sbmc (struct sym_hcb *np) | 2228 | static void sym_int_sbmc(struct Scsi_Host *shost) |
2218 | { | 2229 | { |
2230 | struct sym_hcb *np = sym_get_hcb(shost); | ||
2219 | u_char scsi_mode = INB(np, nc_stest4) & SMODE; | 2231 | u_char scsi_mode = INB(np, nc_stest4) & SMODE; |
2220 | 2232 | ||
2221 | /* | 2233 | /* |
@@ -2228,7 +2240,7 @@ static void sym_int_sbmc (struct sym_hcb *np) | |||
2228 | * Should suspend command processing for a few seconds and | 2240 | * Should suspend command processing for a few seconds and |
2229 | * reinitialize all except the chip. | 2241 | * reinitialize all except the chip. |
2230 | */ | 2242 | */ |
2231 | sym_start_up (np, 2); | 2243 | sym_start_up(shost, 2); |
2232 | } | 2244 | } |
2233 | 2245 | ||
2234 | /* | 2246 | /* |
@@ -2756,8 +2768,11 @@ reset_all: | |||
2756 | * Use at your own decision and risk. | 2768 | * Use at your own decision and risk. |
2757 | */ | 2769 | */ |
2758 | 2770 | ||
2759 | void sym_interrupt (struct sym_hcb *np) | 2771 | irqreturn_t sym_interrupt(struct Scsi_Host *shost) |
2760 | { | 2772 | { |
2773 | struct sym_data *sym_data = shost_priv(shost); | ||
2774 | struct sym_hcb *np = sym_data->ncb; | ||
2775 | struct pci_dev *pdev = sym_data->pdev; | ||
2761 | u_char istat, istatc; | 2776 | u_char istat, istatc; |
2762 | u_char dstat; | 2777 | u_char dstat; |
2763 | u_short sist; | 2778 | u_short sist; |
@@ -2782,7 +2797,7 @@ void sym_interrupt (struct sym_hcb *np) | |||
2782 | } | 2797 | } |
2783 | 2798 | ||
2784 | if (!(istat & (SIP|DIP))) | 2799 | if (!(istat & (SIP|DIP))) |
2785 | return; | 2800 | return (istat & INTF) ? IRQ_HANDLED : IRQ_NONE; |
2786 | 2801 | ||
2787 | #if 0 /* We should never get this one */ | 2802 | #if 0 /* We should never get this one */ |
2788 | if (istat & CABRT) | 2803 | if (istat & CABRT) |
@@ -2809,6 +2824,13 @@ void sym_interrupt (struct sym_hcb *np) | |||
2809 | dstat |= INB(np, nc_dstat); | 2824 | dstat |= INB(np, nc_dstat); |
2810 | istatc = INB(np, nc_istat); | 2825 | istatc = INB(np, nc_istat); |
2811 | istat |= istatc; | 2826 | istat |= istatc; |
2827 | |||
2828 | /* Prevent deadlock waiting on a condition that may | ||
2829 | * never clear. */ | ||
2830 | if (unlikely(sist == 0xffff && dstat == 0xff)) { | ||
2831 | if (pci_channel_offline(pdev)) | ||
2832 | return IRQ_NONE; | ||
2833 | } | ||
2812 | } while (istatc & (SIP|DIP)); | 2834 | } while (istatc & (SIP|DIP)); |
2813 | 2835 | ||
2814 | if (DEBUG_FLAGS & DEBUG_TINY) | 2836 | if (DEBUG_FLAGS & DEBUG_TINY) |
@@ -2842,10 +2864,10 @@ void sym_interrupt (struct sym_hcb *np) | |||
2842 | !(dstat & (MDPE|BF|ABRT|IID))) { | 2864 | !(dstat & (MDPE|BF|ABRT|IID))) { |
2843 | if (sist & PAR) sym_int_par (np, sist); | 2865 | if (sist & PAR) sym_int_par (np, sist); |
2844 | else if (sist & MA) sym_int_ma (np); | 2866 | else if (sist & MA) sym_int_ma (np); |
2845 | else if (dstat & SIR) sym_int_sir (np); | 2867 | else if (dstat & SIR) sym_int_sir(np); |
2846 | else if (dstat & SSI) OUTONB_STD(); | 2868 | else if (dstat & SSI) OUTONB_STD(); |
2847 | else goto unknown_int; | 2869 | else goto unknown_int; |
2848 | return; | 2870 | return IRQ_HANDLED; |
2849 | } | 2871 | } |
2850 | 2872 | ||
2851 | /* | 2873 | /* |
@@ -2861,8 +2883,8 @@ void sym_interrupt (struct sym_hcb *np) | |||
2861 | */ | 2883 | */ |
2862 | if (sist & RST) { | 2884 | if (sist & RST) { |
2863 | printf("%s: SCSI BUS reset detected.\n", sym_name(np)); | 2885 | printf("%s: SCSI BUS reset detected.\n", sym_name(np)); |
2864 | sym_start_up (np, 1); | 2886 | sym_start_up(shost, 1); |
2865 | return; | 2887 | return IRQ_HANDLED; |
2866 | } | 2888 | } |
2867 | 2889 | ||
2868 | OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ | 2890 | OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ |
@@ -2870,11 +2892,11 @@ void sym_interrupt (struct sym_hcb *np) | |||
2870 | 2892 | ||
2871 | if (!(sist & (GEN|HTH|SGE)) && | 2893 | if (!(sist & (GEN|HTH|SGE)) && |
2872 | !(dstat & (MDPE|BF|ABRT|IID))) { | 2894 | !(dstat & (MDPE|BF|ABRT|IID))) { |
2873 | if (sist & SBMC) sym_int_sbmc (np); | 2895 | if (sist & SBMC) sym_int_sbmc(shost); |
2874 | else if (sist & STO) sym_int_sto (np); | 2896 | else if (sist & STO) sym_int_sto (np); |
2875 | else if (sist & UDC) sym_int_udc (np); | 2897 | else if (sist & UDC) sym_int_udc (np); |
2876 | else goto unknown_int; | 2898 | else goto unknown_int; |
2877 | return; | 2899 | return IRQ_HANDLED; |
2878 | } | 2900 | } |
2879 | 2901 | ||
2880 | /* | 2902 | /* |
@@ -2884,12 +2906,12 @@ void sym_interrupt (struct sym_hcb *np) | |||
2884 | * Reset everything. | 2906 | * Reset everything. |
2885 | */ | 2907 | */ |
2886 | 2908 | ||
2887 | sym_log_hard_error(np, sist, dstat); | 2909 | sym_log_hard_error(shost, sist, dstat); |
2888 | 2910 | ||
2889 | if ((sist & (GEN|HTH|SGE)) || | 2911 | if ((sist & (GEN|HTH|SGE)) || |
2890 | (dstat & (MDPE|BF|ABRT|IID))) { | 2912 | (dstat & (MDPE|BF|ABRT|IID))) { |
2891 | sym_start_reset(np); | 2913 | sym_start_reset(np); |
2892 | return; | 2914 | return IRQ_HANDLED; |
2893 | } | 2915 | } |
2894 | 2916 | ||
2895 | unknown_int: | 2917 | unknown_int: |
@@ -2900,6 +2922,7 @@ unknown_int: | |||
2900 | printf( "%s: unknown interrupt(s) ignored, " | 2922 | printf( "%s: unknown interrupt(s) ignored, " |
2901 | "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n", | 2923 | "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n", |
2902 | sym_name(np), istat, dstat, sist); | 2924 | sym_name(np), istat, dstat, sist); |
2925 | return IRQ_NONE; | ||
2903 | } | 2926 | } |
2904 | 2927 | ||
2905 | /* | 2928 | /* |
@@ -3520,7 +3543,8 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num) | |||
3520 | * If we sent a BDR, make upper layer aware of that. | 3543 | * If we sent a BDR, make upper layer aware of that. |
3521 | */ | 3544 | */ |
3522 | if (np->abrt_msg[0] == M_RESET) | 3545 | if (np->abrt_msg[0] == M_RESET) |
3523 | sym_xpt_async_sent_bdr(np, target); | 3546 | starget_printk(KERN_NOTICE, starget, |
3547 | "has been reset\n"); | ||
3524 | break; | 3548 | break; |
3525 | } | 3549 | } |
3526 | 3550 | ||
@@ -4304,7 +4328,7 @@ static void sym_nego_rejected(struct sym_hcb *np, struct sym_tcb *tp, struct sym | |||
4304 | /* | 4328 | /* |
4305 | * chip exception handler for programmed interrupts. | 4329 | * chip exception handler for programmed interrupts. |
4306 | */ | 4330 | */ |
4307 | static void sym_int_sir (struct sym_hcb *np) | 4331 | static void sym_int_sir(struct sym_hcb *np) |
4308 | { | 4332 | { |
4309 | u_char num = INB(np, nc_dsps); | 4333 | u_char num = INB(np, nc_dsps); |
4310 | u32 dsa = INL(np, nc_dsa); | 4334 | u32 dsa = INL(np, nc_dsa); |
@@ -4343,31 +4367,30 @@ static void sym_int_sir (struct sym_hcb *np) | |||
4343 | return; | 4367 | return; |
4344 | /* | 4368 | /* |
4345 | * The device didn't go to MSG OUT phase after having | 4369 | * The device didn't go to MSG OUT phase after having |
4346 | * been selected with ATN. We donnot want to handle | 4370 | * been selected with ATN. We do not want to handle that. |
4347 | * that. | ||
4348 | */ | 4371 | */ |
4349 | case SIR_SEL_ATN_NO_MSG_OUT: | 4372 | case SIR_SEL_ATN_NO_MSG_OUT: |
4350 | printf ("%s:%d: No MSG OUT phase after selection with ATN.\n", | 4373 | scmd_printk(KERN_WARNING, cp->cmd, |
4351 | sym_name (np), target); | 4374 | "No MSG OUT phase after selection with ATN\n"); |
4352 | goto out_stuck; | 4375 | goto out_stuck; |
4353 | /* | 4376 | /* |
4354 | * The device didn't switch to MSG IN phase after | 4377 | * The device didn't switch to MSG IN phase after |
4355 | * having reseleted the initiator. | 4378 | * having reselected the initiator. |
4356 | */ | 4379 | */ |
4357 | case SIR_RESEL_NO_MSG_IN: | 4380 | case SIR_RESEL_NO_MSG_IN: |
4358 | printf ("%s:%d: No MSG IN phase after reselection.\n", | 4381 | scmd_printk(KERN_WARNING, cp->cmd, |
4359 | sym_name (np), target); | 4382 | "No MSG IN phase after reselection\n"); |
4360 | goto out_stuck; | 4383 | goto out_stuck; |
4361 | /* | 4384 | /* |
4362 | * After reselection, the device sent a message that wasn't | 4385 | * After reselection, the device sent a message that wasn't |
4363 | * an IDENTIFY. | 4386 | * an IDENTIFY. |
4364 | */ | 4387 | */ |
4365 | case SIR_RESEL_NO_IDENTIFY: | 4388 | case SIR_RESEL_NO_IDENTIFY: |
4366 | printf ("%s:%d: No IDENTIFY after reselection.\n", | 4389 | scmd_printk(KERN_WARNING, cp->cmd, |
4367 | sym_name (np), target); | 4390 | "No IDENTIFY after reselection\n"); |
4368 | goto out_stuck; | 4391 | goto out_stuck; |
4369 | /* | 4392 | /* |
4370 | * The device reselected a LUN we donnot know about. | 4393 | * The device reselected a LUN we do not know about. |
4371 | */ | 4394 | */ |
4372 | case SIR_RESEL_BAD_LUN: | 4395 | case SIR_RESEL_BAD_LUN: |
4373 | np->msgout[0] = M_RESET; | 4396 | np->msgout[0] = M_RESET; |
@@ -4380,8 +4403,7 @@ static void sym_int_sir (struct sym_hcb *np) | |||
4380 | np->msgout[0] = M_ABORT; | 4403 | np->msgout[0] = M_ABORT; |
4381 | goto out; | 4404 | goto out; |
4382 | /* | 4405 | /* |
4383 | * The device reselected for a tagged nexus that we donnot | 4406 | * The device reselected for a tagged nexus that we do not have. |
4384 | * have. | ||
4385 | */ | 4407 | */ |
4386 | case SIR_RESEL_BAD_I_T_L_Q: | 4408 | case SIR_RESEL_BAD_I_T_L_Q: |
4387 | np->msgout[0] = M_ABORT_TAG; | 4409 | np->msgout[0] = M_ABORT_TAG; |
@@ -4393,8 +4415,8 @@ static void sym_int_sir (struct sym_hcb *np) | |||
4393 | case SIR_RESEL_ABORTED: | 4415 | case SIR_RESEL_ABORTED: |
4394 | np->lastmsg = np->msgout[0]; | 4416 | np->lastmsg = np->msgout[0]; |
4395 | np->msgout[0] = M_NOOP; | 4417 | np->msgout[0] = M_NOOP; |
4396 | printf ("%s:%d: message %x sent on bad reselection.\n", | 4418 | scmd_printk(KERN_WARNING, cp->cmd, |
4397 | sym_name (np), target, np->lastmsg); | 4419 | "message %x sent on bad reselection\n", np->lastmsg); |
4398 | goto out; | 4420 | goto out; |
4399 | /* | 4421 | /* |
4400 | * The SCRIPTS let us know that a message has been | 4422 | * The SCRIPTS let us know that a message has been |
@@ -5578,16 +5600,13 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram | |||
5578 | np->scriptz_ba = vtobus(np->scriptz0); | 5600 | np->scriptz_ba = vtobus(np->scriptz0); |
5579 | 5601 | ||
5580 | if (np->ram_ba) { | 5602 | if (np->ram_ba) { |
5581 | np->scripta_ba = np->ram_ba; | 5603 | np->scripta_ba = np->ram_ba; |
5582 | if (np->features & FE_RAM8K) { | 5604 | if (np->features & FE_RAM8K) { |
5583 | np->ram_ws = 8192; | ||
5584 | np->scriptb_ba = np->scripta_ba + 4096; | 5605 | np->scriptb_ba = np->scripta_ba + 4096; |
5585 | #if 0 /* May get useful for 64 BIT PCI addressing */ | 5606 | #if 0 /* May get useful for 64 BIT PCI addressing */ |
5586 | np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32); | 5607 | np->scr_ram_seg = cpu_to_scr(np->scripta_ba >> 32); |
5587 | #endif | 5608 | #endif |
5588 | } | 5609 | } |
5589 | else | ||
5590 | np->ram_ws = 4096; | ||
5591 | } | 5610 | } |
5592 | 5611 | ||
5593 | /* | 5612 | /* |
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h index 79ab6a177039..ad078805e62b 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h | |||
@@ -883,10 +883,7 @@ struct sym_hcb { | |||
883 | * Physical bus addresses of the chip. | 883 | * Physical bus addresses of the chip. |
884 | */ | 884 | */ |
885 | u32 mmio_ba; /* MMIO 32 bit BUS address */ | 885 | u32 mmio_ba; /* MMIO 32 bit BUS address */ |
886 | int mmio_ws; /* MMIO Window size */ | ||
887 | |||
888 | u32 ram_ba; /* RAM 32 bit BUS address */ | 886 | u32 ram_ba; /* RAM 32 bit BUS address */ |
889 | int ram_ws; /* RAM window size */ | ||
890 | 887 | ||
891 | /* | 888 | /* |
892 | * SCRIPTS virtual and physical bus addresses. | 889 | * SCRIPTS virtual and physical bus addresses. |
@@ -912,14 +909,12 @@ struct sym_hcb { | |||
912 | struct sym_fwb_ba fwb_bas; /* Useful SCRIPTB bus addresses */ | 909 | struct sym_fwb_ba fwb_bas; /* Useful SCRIPTB bus addresses */ |
913 | struct sym_fwz_ba fwz_bas; /* Useful SCRIPTZ bus addresses */ | 910 | struct sym_fwz_ba fwz_bas; /* Useful SCRIPTZ bus addresses */ |
914 | void (*fw_setup)(struct sym_hcb *np, struct sym_fw *fw); | 911 | void (*fw_setup)(struct sym_hcb *np, struct sym_fw *fw); |
915 | void (*fw_patch)(struct sym_hcb *np); | 912 | void (*fw_patch)(struct Scsi_Host *); |
916 | char *fw_name; | 913 | char *fw_name; |
917 | 914 | ||
918 | /* | 915 | /* |
919 | * General controller parameters and configuration. | 916 | * General controller parameters and configuration. |
920 | */ | 917 | */ |
921 | u_short device_id; /* PCI device id */ | ||
922 | u_char revision_id; /* PCI device revision id */ | ||
923 | u_int features; /* Chip features map */ | 918 | u_int features; /* Chip features map */ |
924 | u_char myaddr; /* SCSI id of the adapter */ | 919 | u_char myaddr; /* SCSI id of the adapter */ |
925 | u_char maxburst; /* log base 2 of dwords burst */ | 920 | u_char maxburst; /* log base 2 of dwords burst */ |
@@ -1031,6 +1026,14 @@ struct sym_hcb { | |||
1031 | #endif | 1026 | #endif |
1032 | }; | 1027 | }; |
1033 | 1028 | ||
1029 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 | ||
1030 | #define use_dac(np) 0 | ||
1031 | #define set_dac(np) do { } while (0) | ||
1032 | #else | ||
1033 | #define use_dac(np) (np)->use_dac | ||
1034 | #define set_dac(np) (np)->use_dac = 1 | ||
1035 | #endif | ||
1036 | |||
1034 | #define HCB_BA(np, lbl) (np->hcb_ba + offsetof(struct sym_hcb, lbl)) | 1037 | #define HCB_BA(np, lbl) (np->hcb_ba + offsetof(struct sym_hcb, lbl)) |
1035 | 1038 | ||
1036 | 1039 | ||
@@ -1052,8 +1055,8 @@ void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn); | |||
1052 | #else | 1055 | #else |
1053 | void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); | 1056 | void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); |
1054 | #endif | 1057 | #endif |
1055 | void sym_start_up(struct sym_hcb *np, int reason); | 1058 | void sym_start_up(struct Scsi_Host *, int reason); |
1056 | void sym_interrupt(struct sym_hcb *np); | 1059 | irqreturn_t sym_interrupt(struct Scsi_Host *); |
1057 | int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task); | 1060 | int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task); |
1058 | struct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order); | 1061 | struct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order); |
1059 | void sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp); | 1062 | void sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp); |
@@ -1073,18 +1076,21 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram | |||
1073 | */ | 1076 | */ |
1074 | 1077 | ||
1075 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 | 1078 | #if SYM_CONF_DMA_ADDRESSING_MODE == 0 |
1079 | #define DMA_DAC_MASK DMA_32BIT_MASK | ||
1076 | #define sym_build_sge(np, data, badd, len) \ | 1080 | #define sym_build_sge(np, data, badd, len) \ |
1077 | do { \ | 1081 | do { \ |
1078 | (data)->addr = cpu_to_scr(badd); \ | 1082 | (data)->addr = cpu_to_scr(badd); \ |
1079 | (data)->size = cpu_to_scr(len); \ | 1083 | (data)->size = cpu_to_scr(len); \ |
1080 | } while (0) | 1084 | } while (0) |
1081 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 1 | 1085 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 1 |
1086 | #define DMA_DAC_MASK DMA_40BIT_MASK | ||
1082 | #define sym_build_sge(np, data, badd, len) \ | 1087 | #define sym_build_sge(np, data, badd, len) \ |
1083 | do { \ | 1088 | do { \ |
1084 | (data)->addr = cpu_to_scr(badd); \ | 1089 | (data)->addr = cpu_to_scr(badd); \ |
1085 | (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len); \ | 1090 | (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len); \ |
1086 | } while (0) | 1091 | } while (0) |
1087 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 | 1092 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 |
1093 | #define DMA_DAC_MASK DMA_64BIT_MASK | ||
1088 | int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s); | 1094 | int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s); |
1089 | static __inline void | 1095 | static __inline void |
1090 | sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len) | 1096 | sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len) |
diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c index 15d69298ab6e..5662fbb3ff60 100644 --- a/drivers/scsi/sym53c8xx_2/sym_nvram.c +++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c | |||
@@ -696,7 +696,7 @@ static int sym_read_Tekram_nvram (struct sym_device *np, Tekram_nvram *nvram) | |||
696 | u_short csum; | 696 | u_short csum; |
697 | int x; | 697 | int x; |
698 | 698 | ||
699 | switch (np->device_id) { | 699 | switch (np->pdev->device) { |
700 | case PCI_DEVICE_ID_NCR_53C885: | 700 | case PCI_DEVICE_ID_NCR_53C885: |
701 | case PCI_DEVICE_ID_NCR_53C895: | 701 | case PCI_DEVICE_ID_NCR_53C895: |
702 | case PCI_DEVICE_ID_NCR_53C896: | 702 | case PCI_DEVICE_ID_NCR_53C896: |