summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/mvme147.c107
1 files changed, 57 insertions, 50 deletions
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index e6b2b681fda3..7d1ab414b78f 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -3,6 +3,9 @@
3#include <linux/mm.h> 3#include <linux/mm.h>
4#include <linux/blkdev.h> 4#include <linux/blkdev.h>
5#include <linux/interrupt.h> 5#include <linux/interrupt.h>
6#include <linux/init.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
6 9
7#include <asm/page.h> 10#include <asm/page.h>
8#include <asm/pgtable.h> 11#include <asm/pgtable.h>
@@ -14,9 +17,6 @@
14#include "wd33c93.h" 17#include "wd33c93.h"
15#include "mvme147.h" 18#include "mvme147.h"
16 19
17#include <linux/stat.h>
18
19
20static irqreturn_t mvme147_intr(int irq, void *data) 20static irqreturn_t mvme147_intr(int irq, void *data)
21{ 21{
22 struct Scsi_Host *instance = data; 22 struct Scsi_Host *instance = data;
@@ -65,40 +65,57 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
65 m147_pcc->dma_cntrl = 0; 65 m147_pcc->dma_cntrl = 0;
66} 66}
67 67
68int mvme147_detect(struct scsi_host_template *tpnt) 68static struct scsi_host_template mvme147_host_template = {
69 .module = THIS_MODULE,
70 .proc_name = "MVME147",
71 .name = "MVME147 built-in SCSI",
72 .queuecommand = wd33c93_queuecommand,
73 .eh_abort_handler = wd33c93_abort,
74 .eh_host_reset_handler = wd33c93_host_reset,
75 .show_info = wd33c93_show_info,
76 .write_info = wd33c93_write_info,
77 .can_queue = CAN_QUEUE,
78 .this_id = 7,
79 .sg_tablesize = SG_ALL,
80 .cmd_per_lun = CMD_PER_LUN,
81 .use_clustering = ENABLE_CLUSTERING
82};
83
84static struct Scsi_Host *mvme147_shost;
85
86static int __init mvme147_init(void)
69{ 87{
70 static unsigned char called = 0;
71 struct Scsi_Host *instance;
72 wd33c93_regs regs; 88 wd33c93_regs regs;
73 struct WD33C93_hostdata *hdata; 89 struct WD33C93_hostdata *hdata;
90 int error = -ENOMEM;
74 91
75 if (!MACH_IS_MVME147 || called) 92 if (!MACH_IS_MVME147)
76 return 0; 93 return 0;
77 called++;
78 94
79 tpnt->proc_name = "MVME147"; 95 mvme147_shost = scsi_host_alloc(&mvme147_host_template,
80 tpnt->show_info = wd33c93_show_info, 96 sizeof(struct WD33C93_hostdata));
81 tpnt->write_info = wd33c93_write_info, 97 if (!mvme147_shost)
82
83 instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
84 if (!instance)
85 goto err_out; 98 goto err_out;
99 mvme147_shost->base = 0xfffe4000;
100 mvme147_shost->irq = MVME147_IRQ_SCSI_PORT;
86 101
87 instance->base = 0xfffe4000;
88 instance->irq = MVME147_IRQ_SCSI_PORT;
89 regs.SASR = (volatile unsigned char *)0xfffe4000; 102 regs.SASR = (volatile unsigned char *)0xfffe4000;
90 regs.SCMD = (volatile unsigned char *)0xfffe4001; 103 regs.SCMD = (volatile unsigned char *)0xfffe4001;
91 hdata = shost_priv(instance); 104
105 hdata = shost_priv(mvme147_shost);
92 hdata->no_sync = 0xff; 106 hdata->no_sync = 0xff;
93 hdata->fast = 0; 107 hdata->fast = 0;
94 hdata->dma_mode = CTRL_DMA; 108 hdata->dma_mode = CTRL_DMA;
95 wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
96 109
97 if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, 110 wd33c93_init(mvme147_shost, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
98 "MVME147 SCSI PORT", instance)) 111
112 error = request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
113 "MVME147 SCSI PORT", mvme147_shost);
114 if (error)
99 goto err_unregister; 115 goto err_unregister;
100 if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, 116 error = request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
101 "MVME147 SCSI DMA", instance)) 117 "MVME147 SCSI DMA", mvme147_shost);
118 if (error)
102 goto err_free_irq; 119 goto err_free_irq;
103#if 0 /* Disabled; causes problems booting */ 120#if 0 /* Disabled; causes problems booting */
104 m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ 121 m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */
@@ -112,40 +129,30 @@ int mvme147_detect(struct scsi_host_template *tpnt)
112 m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */ 129 m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */
113 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ 130 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */
114 131
115 return 1; 132 error = scsi_add_host(mvme147_shost, NULL);
133 if (error)
134 goto err_free_irq;
135 scsi_scan_host(mvme147_shost);
136 return 0;
116 137
117err_free_irq: 138err_free_irq:
118 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); 139 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
119err_unregister: 140err_unregister:
120 scsi_unregister(instance); 141 scsi_host_put(mvme147_shost);
121err_out: 142err_out:
122 return 0; 143 return error;
123} 144}
124 145
125static struct scsi_host_template driver_template = { 146static void __exit mvme147_exit(void)
126 .proc_name = "MVME147",
127 .name = "MVME147 built-in SCSI",
128 .detect = mvme147_detect,
129 .release = mvme147_release,
130 .queuecommand = wd33c93_queuecommand,
131 .eh_abort_handler = wd33c93_abort,
132 .eh_host_reset_handler = wd33c93_host_reset,
133 .can_queue = CAN_QUEUE,
134 .this_id = 7,
135 .sg_tablesize = SG_ALL,
136 .cmd_per_lun = CMD_PER_LUN,
137 .use_clustering = ENABLE_CLUSTERING
138};
139
140
141#include "scsi_module.c"
142
143int mvme147_release(struct Scsi_Host *instance)
144{ 147{
145#ifdef MODULE 148 scsi_remove_host(mvme147_shost);
149
146 /* XXX Make sure DMA is stopped! */ 150 /* XXX Make sure DMA is stopped! */
147 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); 151 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost);
148 free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr); 152 free_irq(MVME147_IRQ_SCSI_DMA, mvme147_shost);
149#endif 153
150 return 1; 154 scsi_host_put(mvme147_shost);
151} 155}
156
157module_init(mvme147_init);
158module_exit(mvme147_exit);