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 | |
| 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>
| -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; |
