aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/gvp11.c
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert@linux-m68k.org>2009-05-17 14:44:16 -0400
committerGeert Uytterhoeven <geert@linux-m68k.org>2010-05-26 13:51:07 -0400
commit11ca46eaf207e2fde20f6207b6a3ae7b6295da07 (patch)
treed0574232ea58e5a68624ff8725594d82518c5f54 /drivers/scsi/gvp11.c
parenta8169e6057e9b7dd41c9e3b7a41efebc4bd859c9 (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.c160
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
25static irqreturn_t gvp11_intr(int irq, void *data) 27static 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 172static 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 = &regs->SASR;
191 scmd_3393 = &regs->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
172int __init gvp11_detect(struct scsi_host_template *tpnt) 252int __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;