]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/aic7xxx/aic79xx_osm.c
[SCSI] aic7xxx, aic79xx: deinline functions
[linux-2.6-omap-h63xx.git] / drivers / scsi / aic7xxx / aic79xx_osm.c
index 42c0f14a262cbf8f3b4e3e44c80046b009a9c7b1..6c5287722465b6bfc79c1d7304dac50c1bdb3440 100644 (file)
@@ -315,8 +315,8 @@ uint32_t aic79xx_slowcrc;
  */
 static char *aic79xx = NULL;
 
-MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
-MODULE_DESCRIPTION("Adaptec Aic790X U320 SCSI Host Bus Adapter driver");
+MODULE_AUTHOR("Maintainer: Hannes Reinecke <hare@suse.de>");
+MODULE_DESCRIPTION("Adaptec AIC790X U320 SCSI Host Bus Adapter driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(AIC79XX_DRIVER_VERSION);
 module_param(aic79xx, charp, 0444);
@@ -325,7 +325,7 @@ MODULE_PARM_DESC(aic79xx,
 "      verbose                 Enable verbose/diagnostic logging\n"
 "      allow_memio             Allow device registers to be memory mapped\n"
 "      debug                   Bitmask of debug values to enable\n"
-"      no_reset                Supress initial bus resets\n"
+"      no_reset                Suppress initial bus resets\n"
 "      extended                Enable extended geometry on all controllers\n"
 "      periodic_otag           Send an ordered tagged transaction\n"
 "                              periodically to prevent tag starvation.\n"
@@ -369,10 +369,166 @@ 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);
+uint16_t ahd_inw_atomic(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);
+}
+
+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);
+}
+
+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;
@@ -432,7 +588,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 =
@@ -766,7 +922,6 @@ struct scsi_host_template aic79xx_driver_template = {
        .max_sectors            = 8192,
        .cmd_per_lun            = 2,
        .use_clustering         = ENABLE_CLUSTERING,
-       .use_sg_chaining        = ENABLE_SG_CHAINING,
        .slave_alloc            = ahd_linux_slave_alloc,
        .slave_configure        = ahd_linux_slave_configure,
        .target_alloc           = ahd_linux_target_alloc,
@@ -1414,6 +1569,10 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
        unsigned long flags;
        int nseg;
 
+       nseg = scsi_dma_map(cmd);
+       if (nseg < 0)
+               return SCSI_MLQUEUE_HOST_BUSY;
+
        ahd_lock(ahd, &flags);
 
        /*
@@ -1431,6 +1590,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
        if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
                ahd->flags |= AHD_RESOURCE_SHORTAGE;
                ahd_unlock(ahd, &flags);
+               scsi_dma_unmap(cmd);
                return SCSI_MLQUEUE_HOST_BUSY;
        }
 
@@ -1486,8 +1646,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
        ahd_set_sense_residual(scb, 0);
        scb->sg_count = 0;
 
-       nseg = scsi_dma_map(cmd);
-       BUG_ON(nseg < 0);
        if (nseg > 0) {
                void *sg = scb->sg_list;
                struct scatterlist *cur_seg;
@@ -1784,7 +1942,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
                        if (scb->flags & SCB_SENSE) {
                                sense_size = min(sizeof(struct scsi_sense_data)
                                               - ahd_get_sense_residual(scb),
-                                                (u_long)sizeof(cmd->sense_buffer));
+                                                (u_long)SCSI_SENSE_BUFFERSIZE);
                                sense_offset = 0;
                        } else {
                                /*
@@ -1795,11 +1953,11 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
                                    scb->sense_data;
                                sense_size = min_t(size_t,
                                                scsi_4btoul(siu->sense_length),
-                                               sizeof(cmd->sense_buffer));
+                                               SCSI_SENSE_BUFFERSIZE);
                                sense_offset = SIU_SENSE_OFFSET(siu);
                        }
 
-                       memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+                       memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
                        memcpy(cmd->sense_buffer,
                               ahd_get_sense_buf(ahd, scb)
                               + sense_offset, sense_size);
@@ -1922,7 +2080,7 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
                                struct scsi_sense_data *sense;
                                
                                sense = (struct scsi_sense_data *)
-                                       &cmd->sense_buffer;
+                                       cmd->sense_buffer;
                                if (sense->extra_len >= 5 &&
                                    (sense->add_sense_code == 0x47
                                     || sense->add_sense_code == 0x48))