diff options
Diffstat (limited to 'drivers/scsi/mvme147.c')
-rw-r--r-- | drivers/scsi/mvme147.c | 169 |
1 files changed, 86 insertions, 83 deletions
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index d722235111a8..716d1785cda7 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c | |||
@@ -13,112 +13,116 @@ | |||
13 | #include "wd33c93.h" | 13 | #include "wd33c93.h" |
14 | #include "mvme147.h" | 14 | #include "mvme147.h" |
15 | 15 | ||
16 | #include<linux/stat.h> | 16 | #include <linux/stat.h> |
17 | 17 | ||
18 | #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) | ||
19 | 18 | ||
20 | static struct Scsi_Host *mvme147_host = NULL; | 19 | static struct Scsi_Host *mvme147_host = NULL; |
21 | 20 | ||
22 | static irqreturn_t mvme147_intr (int irq, void *dummy) | 21 | static irqreturn_t mvme147_intr(int irq, void *dummy) |
23 | { | 22 | { |
24 | if (irq == MVME147_IRQ_SCSI_PORT) | 23 | if (irq == MVME147_IRQ_SCSI_PORT) |
25 | wd33c93_intr (mvme147_host); | 24 | wd33c93_intr(mvme147_host); |
26 | else | 25 | else |
27 | m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ | 26 | m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ |
28 | return IRQ_HANDLED; | 27 | return IRQ_HANDLED; |
29 | } | 28 | } |
30 | 29 | ||
31 | static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | 30 | static int dma_setup(struct scsi_cmnd *cmd, int dir_in) |
32 | { | 31 | { |
33 | unsigned char flags = 0x01; | 32 | struct WD33C93_hostdata *hdata = shost_priv(mvme147_host); |
34 | unsigned long addr = virt_to_bus(cmd->SCp.ptr); | 33 | unsigned char flags = 0x01; |
35 | 34 | unsigned long addr = virt_to_bus(cmd->SCp.ptr); | |
36 | /* setup dma direction */ | 35 | |
37 | if (!dir_in) | 36 | /* setup dma direction */ |
38 | flags |= 0x04; | 37 | if (!dir_in) |
39 | 38 | flags |= 0x04; | |
40 | /* remember direction */ | 39 | |
41 | HDATA(mvme147_host)->dma_dir = dir_in; | 40 | /* remember direction */ |
42 | 41 | hdata->dma_dir = dir_in; | |
43 | if (dir_in) | 42 | |
44 | /* invalidate any cache */ | 43 | if (dir_in) { |
45 | cache_clear (addr, cmd->SCp.this_residual); | 44 | /* invalidate any cache */ |
46 | else | 45 | cache_clear(addr, cmd->SCp.this_residual); |
47 | /* push any dirty cache */ | 46 | } else { |
48 | cache_push (addr, cmd->SCp.this_residual); | 47 | /* push any dirty cache */ |
49 | 48 | cache_push(addr, cmd->SCp.this_residual); | |
50 | /* start DMA */ | 49 | } |
51 | m147_pcc->dma_bcr = cmd->SCp.this_residual | (1<<24); | 50 | |
52 | m147_pcc->dma_dadr = addr; | 51 | /* start DMA */ |
53 | m147_pcc->dma_cntrl = flags; | 52 | m147_pcc->dma_bcr = cmd->SCp.this_residual | (1 << 24); |
54 | 53 | m147_pcc->dma_dadr = addr; | |
55 | /* return success */ | 54 | m147_pcc->dma_cntrl = flags; |
56 | return 0; | 55 | |
56 | /* return success */ | ||
57 | return 0; | ||
57 | } | 58 | } |
58 | 59 | ||
59 | static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | 60 | static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, |
60 | int status) | 61 | int status) |
61 | { | 62 | { |
62 | m147_pcc->dma_cntrl = 0; | 63 | m147_pcc->dma_cntrl = 0; |
63 | } | 64 | } |
64 | 65 | ||
65 | int mvme147_detect(struct scsi_host_template *tpnt) | 66 | int mvme147_detect(struct scsi_host_template *tpnt) |
66 | { | 67 | { |
67 | static unsigned char called = 0; | 68 | static unsigned char called = 0; |
68 | wd33c93_regs regs; | 69 | wd33c93_regs regs; |
69 | 70 | struct WD33C93_hostdata *hdata; | |
70 | if (!MACH_IS_MVME147 || called) | 71 | |
71 | return 0; | 72 | if (!MACH_IS_MVME147 || called) |
72 | called++; | 73 | return 0; |
73 | 74 | called++; | |
74 | tpnt->proc_name = "MVME147"; | 75 | |
75 | tpnt->proc_info = &wd33c93_proc_info; | 76 | tpnt->proc_name = "MVME147"; |
76 | 77 | tpnt->proc_info = &wd33c93_proc_info; | |
77 | mvme147_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); | 78 | |
78 | if (!mvme147_host) | 79 | mvme147_host = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); |
79 | goto err_out; | 80 | if (!mvme147_host) |
80 | 81 | goto err_out; | |
81 | mvme147_host->base = 0xfffe4000; | 82 | |
82 | mvme147_host->irq = MVME147_IRQ_SCSI_PORT; | 83 | mvme147_host->base = 0xfffe4000; |
83 | regs.SASR = (volatile unsigned char *)0xfffe4000; | 84 | mvme147_host->irq = MVME147_IRQ_SCSI_PORT; |
84 | regs.SCMD = (volatile unsigned char *)0xfffe4001; | 85 | regs.SASR = (volatile unsigned char *)0xfffe4000; |
85 | HDATA(mvme147_host)->no_sync = 0xff; | 86 | regs.SCMD = (volatile unsigned char *)0xfffe4001; |
86 | HDATA(mvme147_host)->fast = 0; | 87 | hdata = shost_priv(mvme147_host); |
87 | HDATA(mvme147_host)->dma_mode = CTRL_DMA; | 88 | hdata->no_sync = 0xff; |
88 | wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); | 89 | hdata->fast = 0; |
89 | 90 | hdata->dma_mode = CTRL_DMA; | |
90 | if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr)) | 91 | wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); |
91 | goto err_unregister; | 92 | |
92 | if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, "MVME147 SCSI DMA", mvme147_intr)) | 93 | if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, |
93 | goto err_free_irq; | 94 | "MVME147 SCSI PORT", mvme147_intr)) |
95 | goto err_unregister; | ||
96 | if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, | ||
97 | "MVME147 SCSI DMA", mvme147_intr)) | ||
98 | goto err_free_irq; | ||
94 | #if 0 /* Disabled; causes problems booting */ | 99 | #if 0 /* Disabled; causes problems booting */ |
95 | m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ | 100 | m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ |
96 | udelay(100); | 101 | udelay(100); |
97 | m147_pcc->scsi_interrupt = 0x00; /* Negate SCSI bus reset */ | 102 | m147_pcc->scsi_interrupt = 0x00; /* Negate SCSI bus reset */ |
98 | udelay(2000); | 103 | udelay(2000); |
99 | m147_pcc->scsi_interrupt = 0x40; /* Clear bus reset interrupt */ | 104 | m147_pcc->scsi_interrupt = 0x40; /* Clear bus reset interrupt */ |
100 | #endif | 105 | #endif |
101 | m147_pcc->scsi_interrupt = 0x09; /* Enable interrupt */ | 106 | m147_pcc->scsi_interrupt = 0x09; /* Enable interrupt */ |
102 | 107 | ||
103 | m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */ | 108 | m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */ |
104 | m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ | 109 | m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ |
105 | 110 | ||
106 | return 1; | 111 | return 1; |
107 | 112 | ||
108 | err_free_irq: | 113 | err_free_irq: |
109 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); | 114 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); |
110 | err_unregister: | 115 | err_unregister: |
111 | wd33c93_release(); | 116 | scsi_unregister(mvme147_host); |
112 | scsi_unregister(mvme147_host); | 117 | err_out: |
113 | err_out: | 118 | return 0; |
114 | return 0; | ||
115 | } | 119 | } |
116 | 120 | ||
117 | static int mvme147_bus_reset(struct scsi_cmnd *cmd) | 121 | static int mvme147_bus_reset(struct scsi_cmnd *cmd) |
118 | { | 122 | { |
119 | /* FIXME perform bus-specific reset */ | 123 | /* FIXME perform bus-specific reset */ |
120 | 124 | ||
121 | /* FIXME 2: kill this function, and let midlayer fallback to | 125 | /* FIXME 2: kill this function, and let midlayer fallback to |
122 | the same result, calling wd33c93_host_reset() */ | 126 | the same result, calling wd33c93_host_reset() */ |
123 | 127 | ||
124 | spin_lock_irq(cmd->device->host->host_lock); | 128 | spin_lock_irq(cmd->device->host->host_lock); |
@@ -154,10 +158,9 @@ static struct scsi_host_template driver_template = { | |||
154 | int mvme147_release(struct Scsi_Host *instance) | 158 | int mvme147_release(struct Scsi_Host *instance) |
155 | { | 159 | { |
156 | #ifdef MODULE | 160 | #ifdef MODULE |
157 | /* XXX Make sure DMA is stopped! */ | 161 | /* XXX Make sure DMA is stopped! */ |
158 | wd33c93_release(); | 162 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); |
159 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); | 163 | free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr); |
160 | free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr); | ||
161 | #endif | 164 | #endif |
162 | return 1; | 165 | return 1; |
163 | } | 166 | } |