diff options
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_osm.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 95 |
1 files changed, 81 insertions, 14 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 42ad48e09f02..fd2b9785ff4f 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -388,14 +388,83 @@ static int aic7xxx_setup(char *s); | |||
388 | static int ahc_linux_unit; | 388 | static int ahc_linux_unit; |
389 | 389 | ||
390 | 390 | ||
391 | /************************** OS Utility Wrappers *******************************/ | ||
392 | void | ||
393 | ahc_delay(long usec) | ||
394 | { | ||
395 | /* | ||
396 | * udelay on Linux can have problems for | ||
397 | * multi-millisecond waits. Wait at most | ||
398 | * 1024us per call. | ||
399 | */ | ||
400 | while (usec > 0) { | ||
401 | udelay(usec % 1024); | ||
402 | usec -= 1024; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | /***************************** Low Level I/O **********************************/ | ||
407 | uint8_t | ||
408 | ahc_inb(struct ahc_softc * ahc, long port) | ||
409 | { | ||
410 | uint8_t x; | ||
411 | |||
412 | if (ahc->tag == BUS_SPACE_MEMIO) { | ||
413 | x = readb(ahc->bsh.maddr + port); | ||
414 | } else { | ||
415 | x = inb(ahc->bsh.ioport + port); | ||
416 | } | ||
417 | mb(); | ||
418 | return (x); | ||
419 | } | ||
420 | |||
421 | void | ||
422 | ahc_outb(struct ahc_softc * ahc, long port, uint8_t val) | ||
423 | { | ||
424 | if (ahc->tag == BUS_SPACE_MEMIO) { | ||
425 | writeb(val, ahc->bsh.maddr + port); | ||
426 | } else { | ||
427 | outb(val, ahc->bsh.ioport + port); | ||
428 | } | ||
429 | mb(); | ||
430 | } | ||
431 | |||
432 | void | ||
433 | ahc_outsb(struct ahc_softc * ahc, long port, uint8_t *array, int count) | ||
434 | { | ||
435 | int i; | ||
436 | |||
437 | /* | ||
438 | * There is probably a more efficient way to do this on Linux | ||
439 | * but we don't use this for anything speed critical and this | ||
440 | * should work. | ||
441 | */ | ||
442 | for (i = 0; i < count; i++) | ||
443 | ahc_outb(ahc, port, *array++); | ||
444 | } | ||
445 | |||
446 | void | ||
447 | ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count) | ||
448 | { | ||
449 | int i; | ||
450 | |||
451 | /* | ||
452 | * There is probably a more efficient way to do this on Linux | ||
453 | * but we don't use this for anything speed critical and this | ||
454 | * should work. | ||
455 | */ | ||
456 | for (i = 0; i < count; i++) | ||
457 | *array++ = ahc_inb(ahc, port); | ||
458 | } | ||
459 | |||
391 | /********************************* Inlines ************************************/ | 460 | /********************************* Inlines ************************************/ |
392 | static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); | 461 | static void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); |
393 | 462 | ||
394 | static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, | 463 | static int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, |
395 | struct ahc_dma_seg *sg, | 464 | struct ahc_dma_seg *sg, |
396 | dma_addr_t addr, bus_size_t len); | 465 | dma_addr_t addr, bus_size_t len); |
397 | 466 | ||
398 | static __inline void | 467 | static void |
399 | ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) | 468 | ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) |
400 | { | 469 | { |
401 | struct scsi_cmnd *cmd; | 470 | struct scsi_cmnd *cmd; |
@@ -406,7 +475,7 @@ ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) | |||
406 | scsi_dma_unmap(cmd); | 475 | scsi_dma_unmap(cmd); |
407 | } | 476 | } |
408 | 477 | ||
409 | static __inline int | 478 | static int |
410 | ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, | 479 | ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, |
411 | struct ahc_dma_seg *sg, dma_addr_t addr, bus_size_t len) | 480 | struct ahc_dma_seg *sg, dma_addr_t addr, bus_size_t len) |
412 | { | 481 | { |
@@ -442,13 +511,11 @@ ahc_linux_info(struct Scsi_Host *host) | |||
442 | bp = &buffer[0]; | 511 | bp = &buffer[0]; |
443 | ahc = *(struct ahc_softc **)host->hostdata; | 512 | ahc = *(struct ahc_softc **)host->hostdata; |
444 | memset(bp, 0, sizeof(buffer)); | 513 | memset(bp, 0, sizeof(buffer)); |
445 | strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev "); | 514 | strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev " AIC7XXX_DRIVER_VERSION "\n" |
446 | strcat(bp, AIC7XXX_DRIVER_VERSION); | 515 | " <"); |
447 | strcat(bp, "\n"); | ||
448 | strcat(bp, " <"); | ||
449 | strcat(bp, ahc->description); | 516 | strcat(bp, ahc->description); |
450 | strcat(bp, ">\n"); | 517 | strcat(bp, ">\n" |
451 | strcat(bp, " "); | 518 | " "); |
452 | ahc_controller_info(ahc, ahc_info); | 519 | ahc_controller_info(ahc, ahc_info); |
453 | strcat(bp, ahc_info); | 520 | strcat(bp, ahc_info); |
454 | strcat(bp, "\n"); | 521 | strcat(bp, "\n"); |
@@ -964,7 +1031,7 @@ aic7xxx_setup(char *s) | |||
964 | char *p; | 1031 | char *p; |
965 | char *end; | 1032 | char *end; |
966 | 1033 | ||
967 | static struct { | 1034 | static const struct { |
968 | const char *name; | 1035 | const char *name; |
969 | uint32_t *flag; | 1036 | uint32_t *flag; |
970 | } options[] = { | 1037 | } options[] = { |
@@ -2317,7 +2384,7 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period) | |||
2317 | unsigned int ppr_options = tinfo->goal.ppr_options; | 2384 | unsigned int ppr_options = tinfo->goal.ppr_options; |
2318 | unsigned long flags; | 2385 | unsigned long flags; |
2319 | unsigned long offset = tinfo->goal.offset; | 2386 | unsigned long offset = tinfo->goal.offset; |
2320 | struct ahc_syncrate *syncrate; | 2387 | const struct ahc_syncrate *syncrate; |
2321 | 2388 | ||
2322 | if (offset == 0) | 2389 | if (offset == 0) |
2323 | offset = MAX_OFFSET; | 2390 | offset = MAX_OFFSET; |
@@ -2361,7 +2428,7 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset) | |||
2361 | unsigned int ppr_options = 0; | 2428 | unsigned int ppr_options = 0; |
2362 | unsigned int period = 0; | 2429 | unsigned int period = 0; |
2363 | unsigned long flags; | 2430 | unsigned long flags; |
2364 | struct ahc_syncrate *syncrate = NULL; | 2431 | const struct ahc_syncrate *syncrate = NULL; |
2365 | 2432 | ||
2366 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, | 2433 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, |
2367 | starget->channel + 'A', ROLE_INITIATOR); | 2434 | starget->channel + 'A', ROLE_INITIATOR); |
@@ -2391,7 +2458,7 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt) | |||
2391 | unsigned int period = tinfo->goal.period; | 2458 | unsigned int period = tinfo->goal.period; |
2392 | unsigned int width = tinfo->goal.width; | 2459 | unsigned int width = tinfo->goal.width; |
2393 | unsigned long flags; | 2460 | unsigned long flags; |
2394 | struct ahc_syncrate *syncrate; | 2461 | const struct ahc_syncrate *syncrate; |
2395 | 2462 | ||
2396 | if (dt && spi_max_width(starget)) { | 2463 | if (dt && spi_max_width(starget)) { |
2397 | ppr_options |= MSG_EXT_PPR_DT_REQ; | 2464 | ppr_options |= MSG_EXT_PPR_DT_REQ; |