Commit 0d31f8759109cbc1e6fc196d08e6b0e8a9e93b3f

Authored by Finn Thain
Committed by Christoph Hellwig
1 parent 4e70520525

sun3_scsi: Convert to platform device

Convert sun3_scsi to platform device and eliminate scsi_register().

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>

Showing 3 changed files with 245 additions and 222 deletions Side-by-side Diff

arch/m68k/sun3/config.c
... ... @@ -16,6 +16,7 @@
16 16 #include <linux/console.h>
17 17 #include <linux/init.h>
18 18 #include <linux/bootmem.h>
  19 +#include <linux/platform_device.h>
19 20  
20 21 #include <asm/oplib.h>
21 22 #include <asm/setup.h>
... ... @@ -27,6 +28,7 @@
27 28 #include <asm/sun3mmu.h>
28 29 #include <asm/rtc.h>
29 30 #include <asm/machdep.h>
  31 +#include <asm/machines.h>
30 32 #include <asm/idprom.h>
31 33 #include <asm/intersil.h>
32 34 #include <asm/irq.h>
... ... @@ -168,4 +170,63 @@
168 170 sun3_enable_interrupts();
169 171 intersil_clear();
170 172 }
  173 +
  174 +#ifdef CONFIG_SUN3_SCSI
  175 +
  176 +static const struct resource sun3_scsi_vme_rsrc[] __initconst = {
  177 + {
  178 + .flags = IORESOURCE_IRQ,
  179 + .start = SUN3_VEC_VMESCSI0,
  180 + .end = SUN3_VEC_VMESCSI0,
  181 + }, {
  182 + .flags = IORESOURCE_MEM,
  183 + .start = 0xff200000,
  184 + .end = 0xff200021,
  185 + }, {
  186 + .flags = IORESOURCE_IRQ,
  187 + .start = SUN3_VEC_VMESCSI1,
  188 + .end = SUN3_VEC_VMESCSI1,
  189 + }, {
  190 + .flags = IORESOURCE_MEM,
  191 + .start = 0xff204000,
  192 + .end = 0xff204021,
  193 + },
  194 +};
  195 +
  196 +/*
  197 + * Int: level 2 autovector
  198 + * IO: type 1, base 0x00140000, 5 bits phys space: A<4..0>
  199 + */
  200 +static const struct resource sun3_scsi_rsrc[] __initconst = {
  201 + {
  202 + .flags = IORESOURCE_IRQ,
  203 + .start = 2,
  204 + .end = 2,
  205 + }, {
  206 + .flags = IORESOURCE_MEM,
  207 + .start = 0x00140000,
  208 + .end = 0x0014001f,
  209 + },
  210 +};
  211 +
  212 +int __init sun3_platform_init(void)
  213 +{
  214 + switch (idprom->id_machtype) {
  215 + case SM_SUN3 | SM_3_160:
  216 + case SM_SUN3 | SM_3_260:
  217 + platform_device_register_simple("sun3_scsi_vme", -1,
  218 + sun3_scsi_vme_rsrc, ARRAY_SIZE(sun3_scsi_vme_rsrc));
  219 + break;
  220 + case SM_SUN3 | SM_3_50:
  221 + case SM_SUN3 | SM_3_60:
  222 + platform_device_register_simple("sun3_scsi", -1,
  223 + sun3_scsi_rsrc, ARRAY_SIZE(sun3_scsi_rsrc));
  224 + break;
  225 + }
  226 + return 0;
  227 +}
  228 +
  229 +arch_initcall(sun3_platform_init);
  230 +
  231 +#endif
drivers/scsi/sun3_scsi.c
... ... @@ -23,22 +23,15 @@
23 23 */
24 24  
25 25 #include <linux/types.h>
26   -#include <linux/stddef.h>
27   -#include <linux/ctype.h>
28 26 #include <linux/delay.h>
29   -
30 27 #include <linux/module.h>
31   -#include <linux/signal.h>
32 28 #include <linux/ioport.h>
33 29 #include <linux/init.h>
34 30 #include <linux/blkdev.h>
  31 +#include <linux/platform_device.h>
35 32  
36 33 #include <asm/io.h>
37   -
38   -#include <asm/sun3ints.h>
39 34 #include <asm/dvma.h>
40   -#include <asm/idprom.h>
41   -#include <asm/machines.h>
42 35  
43 36 /* dma on! */
44 37 #define REAL_DMA
... ... @@ -59,8 +52,6 @@
59 52 #endif
60 53  
61 54  
62   -static irqreturn_t scsi_sun3_intr(int irq, void *dummy);
63   -
64 55 static int setup_can_queue = -1;
65 56 module_param(setup_can_queue, int, 0);
66 57 static int setup_cmd_per_lun = -1;
67 58  
68 59  
... ... @@ -89,15 +80,14 @@
89 80 /* minimum number of bytes to do dma on */
90 81 #define SUN3_DMA_MINSIZE 128
91 82  
92   -static volatile unsigned char *sun3_scsi_regp;
  83 +static unsigned char *sun3_scsi_regp;
93 84 static volatile struct sun3_dma_regs *dregs;
94   -#ifndef SUN3_SCSI_VME
95   -static struct sun3_udc_regs *udc_regs = NULL;
96   -#endif
  85 +static struct sun3_udc_regs *udc_regs;
97 86 static unsigned char *sun3_dma_orig_addr = NULL;
98 87 static unsigned long sun3_dma_orig_count = 0;
99 88 static int sun3_dma_active = 0;
100 89 static unsigned long last_residual = 0;
  90 +static struct Scsi_Host *default_instance;
101 91  
102 92 /*
103 93 * NCR 5380 register access functions
104 94  
... ... @@ -105,12 +95,12 @@
105 95  
106 96 static inline unsigned char sun3scsi_read(int reg)
107 97 {
108   - return( sun3_scsi_regp[reg] );
  98 + return in_8(sun3_scsi_regp + reg);
109 99 }
110 100  
111 101 static inline void sun3scsi_write(int reg, int value)
112 102 {
113   - sun3_scsi_regp[reg] = value;
  103 + out_8(sun3_scsi_regp + reg, value);
114 104 }
115 105  
116 106 #ifndef SUN3_SCSI_VME
117 107  
... ... @@ -137,192 +127,7 @@
137 127 }
138 128 #endif
139 129  
140   -/*
141   - * XXX: status debug
142   - */
143   -static struct Scsi_Host *default_instance;
144   -
145   -/*
146   - * Function : int sun3scsi_detect(struct scsi_host_template * tpnt)
147   - *
148   - * Purpose : initializes mac NCR5380 driver based on the
149   - * command line / compile time port and irq definitions.
150   - *
151   - * Inputs : tpnt - template for this SCSI adapter.
152   - *
153   - * Returns : 1 if a host adapter was found, 0 if not.
154   - *
155   - */
156   -
157   -static int __init sun3scsi_detect(struct scsi_host_template *tpnt)
158   -{
159   - unsigned long ioaddr, irq;
160   - static int called = 0;
161   - struct Scsi_Host *instance;
162   -#ifdef SUN3_SCSI_VME
163   - int i;
164   - unsigned long addrs[3] = { IOBASE_SUN3_VMESCSI,
165   - IOBASE_SUN3_VMESCSI + 0x4000,
166   - 0 };
167   - unsigned long vecs[3] = { SUN3_VEC_VMESCSI0,
168   - SUN3_VEC_VMESCSI1,
169   - 0 };
170   -#endif
171   -
172   - /* check that this machine has an onboard 5380 */
173   - switch(idprom->id_machtype) {
174   -#ifdef SUN3_SCSI_VME
175   - case SM_SUN3|SM_3_160:
176   - case SM_SUN3|SM_3_260:
177   - break;
178   -#else
179   - case SM_SUN3|SM_3_50:
180   - case SM_SUN3|SM_3_60:
181   - break;
182   -#endif
183   -
184   - default:
185   - return 0;
186   - }
187   -
188   - if(called)
189   - return 0;
190   -
191   -#ifdef SUN3_SCSI_VME
192   - tpnt->proc_name = "Sun3 5380 VME SCSI";
193   -#else
194   - tpnt->proc_name = "Sun3 5380 SCSI";
195   -#endif
196   -
197   - /* setup variables */
198   - if (setup_can_queue > 0)
199   - tpnt->can_queue = setup_can_queue;
200   - if (setup_cmd_per_lun > 0)
201   - tpnt->cmd_per_lun = setup_cmd_per_lun;
202   - if (setup_sg_tablesize >= 0)
203   - tpnt->sg_tablesize = setup_sg_tablesize;
204   -
205   - if (setup_hostid >= 0)
206   - tpnt->this_id = setup_hostid;
207   - else {
208   - /* use 7 as default */
209   - tpnt->this_id = 7;
210   - }
211   -
212   -#ifdef SUN3_SCSI_VME
213   - ioaddr = 0;
214   - for (i = 0; addrs[i] != 0; i++) {
215   - unsigned char x;
216   -
217   - ioaddr = (unsigned long)sun3_ioremap(addrs[i], PAGE_SIZE,
218   - SUN3_PAGE_TYPE_VME16);
219   - irq = vecs[i];
220   - sun3_scsi_regp = (unsigned char *)ioaddr;
221   -
222   - dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8);
223   -
224   - if (sun3_map_test((unsigned long)dregs, &x)) {
225   - unsigned short oldcsr;
226   -
227   - oldcsr = dregs->csr;
228   - dregs->csr = 0;
229   - udelay(SUN3_DMA_DELAY);
230   - if (dregs->csr == 0x1400)
231   - break;
232   -
233   - dregs->csr = oldcsr;
234   - }
235   -
236   - iounmap((void *)ioaddr);
237   - ioaddr = 0;
238   - }
239   -
240   - if (!ioaddr)
241   - return 0;
242   -#else
243   - irq = IRQ_SUN3_SCSI;
244   - ioaddr = (unsigned long)ioremap(IOBASE_SUN3_SCSI, PAGE_SIZE);
245   - sun3_scsi_regp = (unsigned char *)ioaddr;
246   -
247   - dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8);
248   -
249   - if((udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs)))
250   - == NULL) {
251   - printk("SUN3 Scsi couldn't allocate DVMA memory!\n");
252   - return 0;
253   - }
254   -#endif
255   -#ifdef SUPPORT_TAGS
256   - if (setup_use_tagged_queuing < 0)
257   - setup_use_tagged_queuing = 1;
258   -#endif
259   -
260   - instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
261   - if(instance == NULL)
262   - return 0;
263   -
264   - default_instance = instance;
265   -
266   - instance->io_port = (unsigned long) ioaddr;
267   - instance->irq = irq;
268   -
269   - NCR5380_init(instance, 0);
270   -
271   - instance->n_io_port = 32;
272   -
273   - if (request_irq(instance->irq, scsi_sun3_intr,
274   - 0, "Sun3SCSI-5380", instance)) {
275   -#ifndef REAL_DMA
276   - printk("scsi%d: IRQ%d not free, interrupts disabled\n",
277   - instance->host_no, instance->irq);
278   - instance->irq = NO_IRQ;
279   -#else
280   - printk("scsi%d: IRQ%d not free, bailing out\n",
281   - instance->host_no, instance->irq);
282   - return 0;
283   -#endif
284   - }
285   -
286   - dregs->csr = 0;
287   - udelay(SUN3_DMA_DELAY);
288   - dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR;
289   - udelay(SUN3_DMA_DELAY);
290   - dregs->fifo_count = 0;
291   -#ifdef SUN3_SCSI_VME
292   - dregs->fifo_count_hi = 0;
293   - dregs->dma_addr_hi = 0;
294   - dregs->dma_addr_lo = 0;
295   - dregs->dma_count_hi = 0;
296   - dregs->dma_count_lo = 0;
297   -
298   - dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
299   -#endif
300   -
301   - called = 1;
302   -
303 130 #ifdef RESET_BOOT
304   - sun3_scsi_reset_boot(instance);
305   -#endif
306   -
307   - return 1;
308   -}
309   -
310   -static int sun3scsi_release(struct Scsi_Host *shpnt)
311   -{
312   - if (shpnt->irq != NO_IRQ)
313   - free_irq(shpnt->irq, shpnt);
314   -
315   - iounmap((void *)sun3_scsi_regp);
316   -
317   - NCR5380_exit(shpnt);
318   - return 0;
319   -}
320   -
321   -#ifdef RESET_BOOT
322   -/*
323   - * Our 'bus reset on boot' function
324   - */
325   -
326 131 static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
327 132 {
328 133 unsigned long end;
329 134  
... ... @@ -671,11 +476,21 @@
671 476  
672 477 #include "sun3_NCR5380.c"
673 478  
674   -static struct scsi_host_template driver_template = {
  479 +#ifdef SUN3_SCSI_VME
  480 +#define SUN3_SCSI_NAME "Sun3 NCR5380 VME SCSI"
  481 +#define DRV_MODULE_NAME "sun3_scsi_vme"
  482 +#else
  483 +#define SUN3_SCSI_NAME "Sun3 NCR5380 SCSI"
  484 +#define DRV_MODULE_NAME "sun3_scsi"
  485 +#endif
  486 +
  487 +#define PFX DRV_MODULE_NAME ": "
  488 +
  489 +static struct scsi_host_template sun3_scsi_template = {
  490 + .module = THIS_MODULE,
  491 + .proc_name = DRV_MODULE_NAME,
675 492 .show_info = sun3scsi_show_info,
676 493 .name = SUN3_SCSI_NAME,
677   - .detect = sun3scsi_detect,
678   - .release = sun3scsi_release,
679 494 .info = sun3scsi_info,
680 495 .queuecommand = sun3scsi_queue_command,
681 496 .eh_abort_handler = sun3scsi_abort,
682 497  
683 498  
... ... @@ -687,8 +502,173 @@
687 502 .use_clustering = DISABLE_CLUSTERING
688 503 };
689 504  
  505 +static int __init sun3_scsi_probe(struct platform_device *pdev)
  506 +{
  507 + struct Scsi_Host *instance;
  508 + int error;
  509 + struct resource *irq, *mem;
  510 + unsigned char *ioaddr;
  511 +#ifdef SUN3_SCSI_VME
  512 + int i;
  513 +#endif
690 514  
691   -#include "scsi_module.c"
  515 + if (setup_can_queue > 0)
  516 + sun3_scsi_template.can_queue = setup_can_queue;
  517 + if (setup_cmd_per_lun > 0)
  518 + sun3_scsi_template.cmd_per_lun = setup_cmd_per_lun;
  519 + if (setup_sg_tablesize >= 0)
  520 + sun3_scsi_template.sg_tablesize = setup_sg_tablesize;
  521 + if (setup_hostid >= 0)
  522 + sun3_scsi_template.this_id = setup_hostid & 7;
692 523  
  524 +#ifdef SUPPORT_TAGS
  525 + if (setup_use_tagged_queuing < 0)
  526 + setup_use_tagged_queuing = 1;
  527 +#endif
  528 +
  529 +#ifdef SUN3_SCSI_VME
  530 + ioaddr = NULL;
  531 + for (i = 0; i < 2; i++) {
  532 + unsigned char x;
  533 +
  534 + irq = platform_get_resource(pdev, IORESOURCE_IRQ, i);
  535 + mem = platform_get_resource(pdev, IORESOURCE_MEM, i);
  536 + if (!irq || !mem)
  537 + break;
  538 +
  539 + ioaddr = sun3_ioremap(mem->start, resource_size(mem),
  540 + SUN3_PAGE_TYPE_VME16);
  541 + dregs = (struct sun3_dma_regs *)(ioaddr + 8);
  542 +
  543 + if (sun3_map_test((unsigned long)dregs, &x)) {
  544 + unsigned short oldcsr;
  545 +
  546 + oldcsr = dregs->csr;
  547 + dregs->csr = 0;
  548 + udelay(SUN3_DMA_DELAY);
  549 + if (dregs->csr == 0x1400)
  550 + break;
  551 +
  552 + dregs->csr = oldcsr;
  553 + }
  554 +
  555 + iounmap(ioaddr);
  556 + ioaddr = NULL;
  557 + }
  558 + if (!ioaddr)
  559 + return -ENODEV;
  560 +#else
  561 + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  562 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  563 + if (!irq || !mem)
  564 + return -ENODEV;
  565 +
  566 + ioaddr = ioremap(mem->start, resource_size(mem));
  567 + dregs = (struct sun3_dma_regs *)(ioaddr + 8);
  568 +
  569 + udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs));
  570 + if (!udc_regs) {
  571 + pr_err(PFX "couldn't allocate DVMA memory!\n");
  572 + iounmap(ioaddr);
  573 + return -ENOMEM;
  574 + }
  575 +#endif
  576 +
  577 + sun3_scsi_regp = ioaddr;
  578 +
  579 + instance = scsi_host_alloc(&sun3_scsi_template,
  580 + sizeof(struct NCR5380_hostdata));
  581 + if (!instance) {
  582 + error = -ENOMEM;
  583 + goto fail_alloc;
  584 + }
  585 + default_instance = instance;
  586 +
  587 + instance->io_port = (unsigned long)ioaddr;
  588 + instance->irq = irq->start;
  589 +
  590 + NCR5380_init(instance, 0);
  591 +
  592 + error = request_irq(instance->irq, scsi_sun3_intr, 0,
  593 + "NCR5380", instance);
  594 + if (error) {
  595 +#ifdef REAL_DMA
  596 + pr_err(PFX "scsi%d: IRQ %d not free, bailing out\n",
  597 + instance->host_no, instance->irq);
  598 + goto fail_irq;
  599 +#else
  600 + pr_warn(PFX "scsi%d: IRQ %d not free, interrupts disabled\n",
  601 + instance->host_no, instance->irq);
  602 + instance->irq = NO_IRQ;
  603 +#endif
  604 + }
  605 +
  606 + dregs->csr = 0;
  607 + udelay(SUN3_DMA_DELAY);
  608 + dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR;
  609 + udelay(SUN3_DMA_DELAY);
  610 + dregs->fifo_count = 0;
  611 +#ifdef SUN3_SCSI_VME
  612 + dregs->fifo_count_hi = 0;
  613 + dregs->dma_addr_hi = 0;
  614 + dregs->dma_addr_lo = 0;
  615 + dregs->dma_count_hi = 0;
  616 + dregs->dma_count_lo = 0;
  617 +
  618 + dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
  619 +#endif
  620 +
  621 +#ifdef RESET_BOOT
  622 + sun3_scsi_reset_boot(instance);
  623 +#endif
  624 +
  625 + error = scsi_add_host(instance, NULL);
  626 + if (error)
  627 + goto fail_host;
  628 +
  629 + platform_set_drvdata(pdev, instance);
  630 +
  631 + scsi_scan_host(instance);
  632 + return 0;
  633 +
  634 +fail_host:
  635 + if (instance->irq != NO_IRQ)
  636 + free_irq(instance->irq, instance);
  637 +fail_irq:
  638 + NCR5380_exit(instance);
  639 + scsi_host_put(instance);
  640 +fail_alloc:
  641 + if (udc_regs)
  642 + dvma_free(udc_regs);
  643 + iounmap(sun3_scsi_regp);
  644 + return error;
  645 +}
  646 +
  647 +static int __exit sun3_scsi_remove(struct platform_device *pdev)
  648 +{
  649 + struct Scsi_Host *instance = platform_get_drvdata(pdev);
  650 +
  651 + scsi_remove_host(instance);
  652 + if (instance->irq != NO_IRQ)
  653 + free_irq(instance->irq, instance);
  654 + NCR5380_exit(instance);
  655 + scsi_host_put(instance);
  656 + if (udc_regs)
  657 + dvma_free(udc_regs);
  658 + iounmap(sun3_scsi_regp);
  659 + return 0;
  660 +}
  661 +
  662 +static struct platform_driver sun3_scsi_driver = {
  663 + .remove = __exit_p(sun3_scsi_remove),
  664 + .driver = {
  665 + .name = DRV_MODULE_NAME,
  666 + .owner = THIS_MODULE,
  667 + },
  668 +};
  669 +
  670 +module_platform_driver_probe(sun3_scsi_driver, sun3_scsi_probe);
  671 +
  672 +MODULE_ALIAS("platform:" DRV_MODULE_NAME);
693 673 MODULE_LICENSE("GPL");
drivers/scsi/sun3_scsi.h
... ... @@ -18,24 +18,7 @@
18 18 #ifndef SUN3_SCSI_H
19 19 #define SUN3_SCSI_H
20 20  
21   -/*
22   - * Int: level 2 autovector
23   - * IO: type 1, base 0x00140000, 5 bits phys space: A<4..0>
24   - */
25   -#define IRQ_SUN3_SCSI 2
26   -#define IOBASE_SUN3_SCSI 0x00140000
27   -
28   -#define IOBASE_SUN3_VMESCSI 0xff200000
29   -
30 21 #define MAX_TAGS 32
31   -
32   -#include <scsi/scsicam.h>
33   -
34   -#ifdef SUN3_SCSI_VME
35   -#define SUN3_SCSI_NAME "Sun3 NCR5380 VME SCSI"
36   -#else
37   -#define SUN3_SCSI_NAME "Sun3 NCR5380 SCSI"
38   -#endif
39 22  
40 23 #define NCR5380_implementation_fields /* none */
41 24