diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2009-05-17 14:44:16 -0400 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2010-05-26 13:51:07 -0400 |
commit | 11ca46eaf207e2fde20f6207b6a3ae7b6295da07 (patch) | |
tree | d0574232ea58e5a68624ff8725594d82518c5f54 /drivers/scsi/gvp11.c | |
parent | a8169e6057e9b7dd41c9e3b7a41efebc4bd859c9 (diff) |
m68k/scsi: gvp11 - Extract check_wd33c93()
Acked-by: James Bottomley <James.Bottomley@suse.de>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'drivers/scsi/gvp11.c')
-rw-r--r-- | drivers/scsi/gvp11.c | 160 |
1 files changed, 83 insertions, 77 deletions
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 777972e6bbf3..59a7bff53e13 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/stat.h> | 22 | #include <linux/stat.h> |
23 | 23 | ||
24 | 24 | ||
25 | #define CHECK_WD33C93 | ||
26 | |||
25 | static irqreturn_t gvp11_intr(int irq, void *data) | 27 | static irqreturn_t gvp11_intr(int irq, void *data) |
26 | { | 28 | { |
27 | struct Scsi_Host *instance = data; | 29 | struct Scsi_Host *instance = data; |
@@ -167,7 +169,85 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | |||
167 | } | 169 | } |
168 | } | 170 | } |
169 | 171 | ||
170 | #define CHECK_WD33C93 | 172 | static int __init check_wd33c93(gvp11_scsiregs *regs) |
173 | { | ||
174 | #ifdef CHECK_WD33C93 | ||
175 | volatile unsigned char *sasr_3393, *scmd_3393; | ||
176 | unsigned char save_sasr; | ||
177 | unsigned char q, qq; | ||
178 | |||
179 | /* | ||
180 | * These darn GVP boards are a problem - it can be tough to tell | ||
181 | * whether or not they include a SCSI controller. This is the | ||
182 | * ultimate Yet-Another-GVP-Detection-Hack in that it actually | ||
183 | * probes for a WD33c93 chip: If we find one, it's extremely | ||
184 | * likely that this card supports SCSI, regardless of Product_ | ||
185 | * Code, Board_Size, etc. | ||
186 | */ | ||
187 | |||
188 | /* Get pointers to the presumed register locations and save contents */ | ||
189 | |||
190 | sasr_3393 = ®s->SASR; | ||
191 | scmd_3393 = ®s->SCMD; | ||
192 | save_sasr = *sasr_3393; | ||
193 | |||
194 | /* First test the AuxStatus Reg */ | ||
195 | |||
196 | q = *sasr_3393; /* read it */ | ||
197 | if (q & 0x08) /* bit 3 should always be clear */ | ||
198 | return -ENODEV; | ||
199 | *sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */ | ||
200 | if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */ | ||
201 | *sasr_3393 = save_sasr; /* Oops - restore this byte */ | ||
202 | return -ENODEV; | ||
203 | } | ||
204 | if (*sasr_3393 != q) { /* should still read the same */ | ||
205 | *sasr_3393 = save_sasr; /* Oops - restore this byte */ | ||
206 | return -ENODEV; | ||
207 | } | ||
208 | if (*scmd_3393 != q) /* and so should the image at 0x1f */ | ||
209 | return -ENODEV; | ||
210 | |||
211 | /* | ||
212 | * Ok, we probably have a wd33c93, but let's check a few other places | ||
213 | * for good measure. Make sure that this works for both 'A and 'B | ||
214 | * chip versions. | ||
215 | */ | ||
216 | |||
217 | *sasr_3393 = WD_SCSI_STATUS; | ||
218 | q = *scmd_3393; | ||
219 | *sasr_3393 = WD_SCSI_STATUS; | ||
220 | *scmd_3393 = ~q; | ||
221 | *sasr_3393 = WD_SCSI_STATUS; | ||
222 | qq = *scmd_3393; | ||
223 | *sasr_3393 = WD_SCSI_STATUS; | ||
224 | *scmd_3393 = q; | ||
225 | if (qq != q) /* should be read only */ | ||
226 | return -ENODEV; | ||
227 | *sasr_3393 = 0x1e; /* this register is unimplemented */ | ||
228 | q = *scmd_3393; | ||
229 | *sasr_3393 = 0x1e; | ||
230 | *scmd_3393 = ~q; | ||
231 | *sasr_3393 = 0x1e; | ||
232 | qq = *scmd_3393; | ||
233 | *sasr_3393 = 0x1e; | ||
234 | *scmd_3393 = q; | ||
235 | if (qq != q || qq != 0xff) /* should be read only, all 1's */ | ||
236 | return -ENODEV; | ||
237 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
238 | q = *scmd_3393; | ||
239 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
240 | *scmd_3393 = ~q; | ||
241 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
242 | qq = *scmd_3393; | ||
243 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
244 | *scmd_3393 = q; | ||
245 | if (qq != (~q & 0xff)) /* should be read/write */ | ||
246 | return -ENODEV; | ||
247 | #endif /* CHECK_WD33C93 */ | ||
248 | |||
249 | return 0; | ||
250 | } | ||
171 | 251 | ||
172 | int __init gvp11_detect(struct scsi_host_template *tpnt) | 252 | int __init gvp11_detect(struct scsi_host_template *tpnt) |
173 | { | 253 | { |
@@ -181,11 +261,6 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) | |||
181 | gvp11_scsiregs *regs; | 261 | gvp11_scsiregs *regs; |
182 | wd33c93_regs wdregs; | 262 | wd33c93_regs wdregs; |
183 | int num_gvp11 = 0; | 263 | int num_gvp11 = 0; |
184 | #ifdef CHECK_WD33C93 | ||
185 | volatile unsigned char *sasr_3393, *scmd_3393; | ||
186 | unsigned char save_sasr; | ||
187 | unsigned char q, qq; | ||
188 | #endif | ||
189 | 264 | ||
190 | if (!MACH_IS_AMIGA || called) | 265 | if (!MACH_IS_AMIGA || called) |
191 | return 0; | 266 | return 0; |
@@ -226,77 +301,9 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) | |||
226 | if (!request_mem_region(address, 256, "wd33c93")) | 301 | if (!request_mem_region(address, 256, "wd33c93")) |
227 | continue; | 302 | continue; |
228 | 303 | ||
229 | #ifdef CHECK_WD33C93 | 304 | regs = (gvp11_scsiregs *)(ZTWO_VADDR(address)); |
230 | 305 | if (check_wd33c93(regs)) | |
231 | /* | ||
232 | * These darn GVP boards are a problem - it can be tough to tell | ||
233 | * whether or not they include a SCSI controller. This is the | ||
234 | * ultimate Yet-Another-GVP-Detection-Hack in that it actually | ||
235 | * probes for a WD33c93 chip: If we find one, it's extremely | ||
236 | * likely that this card supports SCSI, regardless of Product_ | ||
237 | * Code, Board_Size, etc. | ||
238 | */ | ||
239 | |||
240 | /* Get pointers to the presumed register locations and save contents */ | ||
241 | |||
242 | sasr_3393 = &(((gvp11_scsiregs *)(ZTWO_VADDR(address)))->SASR); | ||
243 | scmd_3393 = &(((gvp11_scsiregs *)(ZTWO_VADDR(address)))->SCMD); | ||
244 | save_sasr = *sasr_3393; | ||
245 | |||
246 | /* First test the AuxStatus Reg */ | ||
247 | |||
248 | q = *sasr_3393; /* read it */ | ||
249 | if (q & 0x08) /* bit 3 should always be clear */ | ||
250 | goto release; | ||
251 | *sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */ | ||
252 | if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */ | ||
253 | *sasr_3393 = save_sasr; /* Oops - restore this byte */ | ||
254 | goto release; | ||
255 | } | ||
256 | if (*sasr_3393 != q) { /* should still read the same */ | ||
257 | *sasr_3393 = save_sasr; /* Oops - restore this byte */ | ||
258 | goto release; | ||
259 | } | ||
260 | if (*scmd_3393 != q) /* and so should the image at 0x1f */ | ||
261 | goto release; | ||
262 | |||
263 | /* | ||
264 | * Ok, we probably have a wd33c93, but let's check a few other places | ||
265 | * for good measure. Make sure that this works for both 'A and 'B | ||
266 | * chip versions. | ||
267 | */ | ||
268 | |||
269 | *sasr_3393 = WD_SCSI_STATUS; | ||
270 | q = *scmd_3393; | ||
271 | *sasr_3393 = WD_SCSI_STATUS; | ||
272 | *scmd_3393 = ~q; | ||
273 | *sasr_3393 = WD_SCSI_STATUS; | ||
274 | qq = *scmd_3393; | ||
275 | *sasr_3393 = WD_SCSI_STATUS; | ||
276 | *scmd_3393 = q; | ||
277 | if (qq != q) /* should be read only */ | ||
278 | goto release; | ||
279 | *sasr_3393 = 0x1e; /* this register is unimplemented */ | ||
280 | q = *scmd_3393; | ||
281 | *sasr_3393 = 0x1e; | ||
282 | *scmd_3393 = ~q; | ||
283 | *sasr_3393 = 0x1e; | ||
284 | qq = *scmd_3393; | ||
285 | *sasr_3393 = 0x1e; | ||
286 | *scmd_3393 = q; | ||
287 | if (qq != q || qq != 0xff) /* should be read only, all 1's */ | ||
288 | goto release; | 306 | goto release; |
289 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
290 | q = *scmd_3393; | ||
291 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
292 | *scmd_3393 = ~q; | ||
293 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
294 | qq = *scmd_3393; | ||
295 | *sasr_3393 = WD_TIMEOUT_PERIOD; | ||
296 | *scmd_3393 = q; | ||
297 | if (qq != (~q & 0xff)) /* should be read/write */ | ||
298 | goto release; | ||
299 | #endif | ||
300 | 307 | ||
301 | instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); | 308 | instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); |
302 | if (instance == NULL) | 309 | if (instance == NULL) |
@@ -311,7 +318,6 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) | |||
311 | else | 318 | else |
312 | hdata->dma_xfer_mask = default_dma_xfer_mask; | 319 | hdata->dma_xfer_mask = default_dma_xfer_mask; |
313 | 320 | ||
314 | regs = (gvp11_scsiregs *)(instance->base); | ||
315 | regs->secret2 = 1; | 321 | regs->secret2 = 1; |
316 | regs->secret1 = 0; | 322 | regs->secret1 = 0; |
317 | regs->secret3 = 15; | 323 | regs->secret3 = 15; |