]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/aic7xxx/aic79xx_osm.c
Merge commit 'v2.6.28-rc4' into timers/rtc
[linux-2.6-omap-h63xx.git] / drivers / scsi / aic7xxx / aic79xx_osm.c
index 0081aa357c8b09c7f5f939d76c4bddfd2b8de65f..0f829b3b8ab75e0f990e420045bd7007b4f6855f 100644 (file)
@@ -193,7 +193,7 @@ struct ahd_linux_iocell_opts
 #define AIC79XX_PRECOMP_INDEX  0
 #define AIC79XX_SLEWRATE_INDEX 1
 #define AIC79XX_AMPLITUDE_INDEX        2
-static struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
+static const struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
 {
        AIC79XX_DEFAULT_IOOPTS,
        AIC79XX_DEFAULT_IOOPTS,
@@ -369,10 +369,167 @@ static void ahd_release_simq(struct ahd_softc *ahd);
 static int ahd_linux_unit;
 
 
+/************************** OS Utility Wrappers *******************************/
+void ahd_delay(long);
+void
+ahd_delay(long usec)
+{
+       /*
+        * udelay on Linux can have problems for
+        * multi-millisecond waits.  Wait at most
+        * 1024us per call.
+        */
+       while (usec > 0) {
+               udelay(usec % 1024);
+               usec -= 1024;
+       }
+}
+
+
+/***************************** Low Level I/O **********************************/
+uint8_t ahd_inb(struct ahd_softc * ahd, long port);
+void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
+void ahd_outw_atomic(struct ahd_softc * ahd,
+                                    long port, uint16_t val);
+void ahd_outsb(struct ahd_softc * ahd, long port,
+                              uint8_t *, int count);
+void ahd_insb(struct ahd_softc * ahd, long port,
+                              uint8_t *, int count);
+
+uint8_t
+ahd_inb(struct ahd_softc * ahd, long port)
+{
+       uint8_t x;
+
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               x = readb(ahd->bshs[0].maddr + port);
+       } else {
+               x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
+       }
+       mb();
+       return (x);
+}
+
+#if 0 /* unused */
+static uint16_t
+ahd_inw_atomic(struct ahd_softc * ahd, long port)
+{
+       uint8_t x;
+
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               x = readw(ahd->bshs[0].maddr + port);
+       } else {
+               x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
+       }
+       mb();
+       return (x);
+}
+#endif
+
+void
+ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
+{
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               writeb(val, ahd->bshs[0].maddr + port);
+       } else {
+               outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
+       }
+       mb();
+}
+
+void
+ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
+{
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               writew(val, ahd->bshs[0].maddr + port);
+       } else {
+               outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
+       }
+       mb();
+}
+
+void
+ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
+{
+       int i;
+
+       /*
+        * There is probably a more efficient way to do this on Linux
+        * but we don't use this for anything speed critical and this
+        * should work.
+        */
+       for (i = 0; i < count; i++)
+               ahd_outb(ahd, port, *array++);
+}
+
+void
+ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
+{
+       int i;
+
+       /*
+        * There is probably a more efficient way to do this on Linux
+        * but we don't use this for anything speed critical and this
+        * should work.
+        */
+       for (i = 0; i < count; i++)
+               *array++ = ahd_inb(ahd, port);
+}
+
+/******************************* PCI Routines *********************************/
+uint32_t
+ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
+{
+       switch (width) {
+       case 1:
+       {
+               uint8_t retval;
+
+               pci_read_config_byte(pci, reg, &retval);
+               return (retval);
+       }
+       case 2:
+       {
+               uint16_t retval;
+               pci_read_config_word(pci, reg, &retval);
+               return (retval);
+       }
+       case 4:
+       {
+               uint32_t retval;
+               pci_read_config_dword(pci, reg, &retval);
+               return (retval);
+       }
+       default:
+               panic("ahd_pci_read_config: Read size too big");
+               /* NOTREACHED */
+               return (0);
+       }
+}
+
+void
+ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
+{
+       switch (width) {
+       case 1:
+               pci_write_config_byte(pci, reg, value);
+               break;
+       case 2:
+               pci_write_config_word(pci, reg, value);
+               break;
+       case 4:
+               pci_write_config_dword(pci, reg, value);
+               break;
+       default:
+               panic("ahd_pci_write_config: Write size too big");
+               /* NOTREACHED */
+       }
+}
+
 /****************************** Inlines ***************************************/
-static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
+static void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
 
-static __inline void
+static void
 ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
 {
        struct scsi_cmnd *cmd;
@@ -400,13 +557,11 @@ ahd_linux_info(struct Scsi_Host *host)
        bp = &buffer[0];
        ahd = *(struct ahd_softc **)host->hostdata;
        memset(bp, 0, sizeof(buffer));
-       strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev ");
-       strcat(bp, AIC79XX_DRIVER_VERSION);
-       strcat(bp, "\n");
-       strcat(bp, "        <");
+       strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev " AIC79XX_DRIVER_VERSION "\n"
+                       "        <");
        strcat(bp, ahd->description);
-       strcat(bp, ">\n");
-       strcat(bp, "        ");
+       strcat(bp, ">\n"
+                       "        ");
        ahd_controller_info(ahd, ahd_info);
        strcat(bp, ahd_info);
 
@@ -432,7 +587,7 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
        return rtn;
 }
 
-static inline struct scsi_target **
+static struct scsi_target **
 ahd_linux_target_in_softc(struct scsi_target *starget)
 {
        struct  ahd_softc *ahd =
@@ -991,7 +1146,7 @@ aic79xx_setup(char *s)
        char   *p;
        char   *end;
 
-       static struct {
+       static const struct {
                const char *name;
                uint32_t *flag;
        } options[] = {
@@ -1223,7 +1378,7 @@ ahd_platform_init(struct ahd_softc *ahd)
         * Lookup and commit any modified IO Cell options.
         */
        if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
-               struct ahd_linux_iocell_opts *iocell_opts;
+               const struct ahd_linux_iocell_opts *iocell_opts;
 
                iocell_opts = &aic79xx_iocell_info[ahd->unit];
                if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP)
@@ -2613,7 +2768,7 @@ static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
                uint8_t precomp;
 
                if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
-                       struct ahd_linux_iocell_opts *iocell_opts;
+                       const struct ahd_linux_iocell_opts *iocell_opts;
 
                        iocell_opts = &aic79xx_iocell_info[ahd->unit];
                        precomp = iocell_opts->precomp;