[SCSI] fcoe, libfc: fix double fcoe_softc memory alloc
[safe/jmp/linux-2.6] / drivers / scsi / advansys.c
index 93b1a47..7507d8b 100644 (file)
 #define ASC_DCNT  __u32                /* Unsigned Data count type. */
 #define ASC_SDCNT __s32                /* Signed Data count type. */
 
-/*
- * These macros are used to convert a virtual address to a
- * 32-bit value. This currently can be used on Linux Alpha
- * which uses 64-bit virtual address but a 32-bit bus address.
- * This is likely to break in the future, but doing this now
- * will give us time to change the HW and FW to handle 64-bit
- * addresses.
- */
-#define ASC_VADDR_TO_U32   virt_to_bus
-#define ASC_U32_TO_VADDR   bus_to_virt
-
 typedef unsigned char uchar;
 
 #ifndef TRUE
@@ -131,7 +120,7 @@ typedef unsigned char uchar;
 #define CC_VERY_LONG_SG_LIST 0
 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
 
-#define PortAddr                 unsigned short        /* port address size  */
+#define PortAddr                 unsigned int  /* port address size  */
 #define inp(port)                inb(port)
 #define outp(port, byte)         outb((byte), (port))
 
@@ -540,7 +529,6 @@ typedef struct asc_dvc_cfg {
        ushort mcode_date;
        ushort mcode_version;
        uchar max_tag_qng[ASC_MAX_TID + 1];
-       uchar *overrun_buf;
        uchar sdtr_period_offset[ASC_MAX_TID + 1];
        uchar adapter_info[6];
 } ASC_DVC_CFG;
@@ -562,6 +550,7 @@ typedef struct asc_dvc_cfg {
 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
 #define ASC_MIN_TAGGED_CMD  7
 #define ASC_MAX_SCSI_RESET_WAIT      30
+#define ASC_OVERRUN_BSIZE              64
 
 struct asc_dvc_var;            /* Forward Declaration. */
 
@@ -577,6 +566,8 @@ typedef struct asc_dvc_var {
        ASC_SCSI_BIT_ID_TYPE unit_not_ready;
        ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
        ASC_SCSI_BIT_ID_TYPE start_motor;
+       uchar *overrun_buf;
+       dma_addr_t overrun_dma;
        uchar scsi_reset_wait;
        uchar chip_no;
        char is_in_int;
@@ -601,6 +592,8 @@ typedef struct asc_dvc_var {
        uchar min_sdtr_index;
        uchar max_sdtr_index;
        struct asc_board *drv_ptr;
+       int ptr_map_count;
+       void **ptr_map;
        ASC_DCNT uc_break;
 } ASC_DVC_VAR;
 
@@ -677,7 +670,6 @@ typedef struct asceep_config {
 #define ASC_EEP_CMD_WRITE         0x40
 #define ASC_EEP_CMD_WRITE_ABLE    0x30
 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
-#define ASC_OVERRUN_BSIZE  0x00000048UL
 #define ASCV_MSGOUT_BEG         0x0000
 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
@@ -983,28 +975,14 @@ typedef struct asc_mc_saved {
  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
  * structures or 255 scatter-gather elements.
- *
  */
 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
 
 /*
- * Define Adv Library required maximum number of scatter-gather
- * elements per request.
+ * Define maximum number of scatter-gather elements per request.
  */
 #define ADV_MAX_SG_LIST         255
-
-/* Number of SG blocks needed. */
-#define ADV_NUM_SG_BLOCK \
-    ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
-
-/* Total contiguous memory needed for SG blocks. */
-#define ADV_SG_TOTAL_MEM_SIZE \
-    (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
-
-#define ADV_PAGE_SIZE PAGE_SIZE
-
-#define ADV_NUM_PAGE_CROSSING \
-    ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
+#define NO_OF_SG_PER_BLOCK              15
 
 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
 #define ADV_EEP_DVC_CFG_END             (0x15)
@@ -1793,8 +1771,7 @@ typedef struct adv_carr_t {
 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
 
 #define ADV_CARRIER_NUM_PAGE_CROSSING \
-    (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
-        (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
+    (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + (PAGE_SIZE - 1))/PAGE_SIZE)
 
 #define ADV_CARRIER_BUFSIZE \
     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
@@ -1839,55 +1816,6 @@ typedef struct adv_dvc_cfg {
 struct adv_dvc_var;
 struct adv_scsi_req_q;
 
-/*
- * Adapter operation variable structure.
- *
- * One structure is required per host adapter.
- *
- * Field naming convention:
- *
- *  *_able indicates both whether a feature should be enabled or disabled
- *  and whether a device isi capable of the feature. At initialization
- *  this field may be set, but later if a device is found to be incapable
- *  of the feature, the field is cleared.
- */
-typedef struct adv_dvc_var {
-       AdvPortAddr iop_base;   /* I/O port address */
-       ushort err_code;        /* fatal error code */
-       ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
-       ushort wdtr_able;       /* try WDTR for a device */
-       ushort sdtr_able;       /* try SDTR for a device */
-       ushort ultra_able;      /* try SDTR Ultra speed for a device */
-       ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
-       ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
-       ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
-       ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
-       ushort tagqng_able;     /* try tagged queuing with a device */
-       ushort ppr_able;        /* PPR message capable per TID bitmask. */
-       uchar max_dvc_qng;      /* maximum number of tagged commands per device */
-       ushort start_motor;     /* start motor command allowed */
-       uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
-       uchar chip_no;          /* should be assigned by caller */
-       uchar max_host_qng;     /* maximum number of Q'ed command allowed */
-       ushort no_scam;         /* scam_tolerant of EEPROM */
-       struct asc_board *drv_ptr;      /* driver pointer to private structure */
-       uchar chip_scsi_id;     /* chip SCSI target ID */
-       uchar chip_type;
-       uchar bist_err_code;
-       ADV_CARR_T *carrier_buf;
-       ADV_CARR_T *carr_freelist;      /* Carrier free list. */
-       ADV_CARR_T *icq_sp;     /* Initiator command queue stopper pointer. */
-       ADV_CARR_T *irq_sp;     /* Initiator response queue stopper pointer. */
-       ushort carr_pending_cnt;        /* Count of pending carriers. */
-       /*
-        * Note: The following fields will not be used after initialization. The
-        * driver may discard the buffer after initialization is done.
-        */
-       ADV_DVC_CFG *cfg;       /* temporary configuration structure  */
-} ADV_DVC_VAR;
-
-#define NO_OF_SG_PER_BLOCK              15
-
 typedef struct asc_sg_block {
        uchar reserved1;
        uchar reserved2;
@@ -1946,6 +1874,83 @@ typedef struct adv_scsi_req_q {
 } ADV_SCSI_REQ_Q;
 
 /*
+ * The following two structures are used to process Wide Board requests.
+ *
+ * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
+ * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
+ * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
+ * Mid-Level SCSI request structure.
+ *
+ * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
+ * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
+ * up to 255 scatter-gather elements may be used per request or
+ * ADV_SCSI_REQ_Q.
+ *
+ * Both structures must be 32 byte aligned.
+ */
+typedef struct adv_sgblk {
+       ADV_SG_BLOCK sg_block;  /* Sgblock structure. */
+       uchar align[32];        /* Sgblock structure padding. */
+       struct adv_sgblk *next_sgblkp;  /* Next scatter-gather structure. */
+} adv_sgblk_t;
+
+typedef struct adv_req {
+       ADV_SCSI_REQ_Q scsi_req_q;      /* Adv Library request structure. */
+       uchar align[32];        /* Request structure padding. */
+       struct scsi_cmnd *cmndp;        /* Mid-Level SCSI command pointer. */
+       adv_sgblk_t *sgblkp;    /* Adv Library scatter-gather pointer. */
+       struct adv_req *next_reqp;      /* Next Request Structure. */
+} adv_req_t;
+
+/*
+ * Adapter operation variable structure.
+ *
+ * One structure is required per host adapter.
+ *
+ * Field naming convention:
+ *
+ *  *_able indicates both whether a feature should be enabled or disabled
+ *  and whether a device isi capable of the feature. At initialization
+ *  this field may be set, but later if a device is found to be incapable
+ *  of the feature, the field is cleared.
+ */
+typedef struct adv_dvc_var {
+       AdvPortAddr iop_base;   /* I/O port address */
+       ushort err_code;        /* fatal error code */
+       ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
+       ushort wdtr_able;       /* try WDTR for a device */
+       ushort sdtr_able;       /* try SDTR for a device */
+       ushort ultra_able;      /* try SDTR Ultra speed for a device */
+       ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
+       ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
+       ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
+       ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
+       ushort tagqng_able;     /* try tagged queuing with a device */
+       ushort ppr_able;        /* PPR message capable per TID bitmask. */
+       uchar max_dvc_qng;      /* maximum number of tagged commands per device */
+       ushort start_motor;     /* start motor command allowed */
+       uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
+       uchar chip_no;          /* should be assigned by caller */
+       uchar max_host_qng;     /* maximum number of Q'ed command allowed */
+       ushort no_scam;         /* scam_tolerant of EEPROM */
+       struct asc_board *drv_ptr;      /* driver pointer to private structure */
+       uchar chip_scsi_id;     /* chip SCSI target ID */
+       uchar chip_type;
+       uchar bist_err_code;
+       ADV_CARR_T *carrier_buf;
+       ADV_CARR_T *carr_freelist;      /* Carrier free list. */
+       ADV_CARR_T *icq_sp;     /* Initiator command queue stopper pointer. */
+       ADV_CARR_T *irq_sp;     /* Initiator response queue stopper pointer. */
+       ushort carr_pending_cnt;        /* Count of pending carriers. */
+       struct adv_req *orig_reqp;      /* adv_req_t memory block. */
+       /*
+        * Note: The following fields will not be used after initialization. The
+        * driver may discard the buffer after initialization is done.
+        */
+       ADV_DVC_CFG *cfg;       /* temporary configuration structure  */
+} ADV_DVC_VAR;
+
+/*
  * Microcode idle loop commands
  */
 #define IDLE_CMD_COMPLETED           0
@@ -2147,16 +2152,6 @@ do { \
 #define QHSTA_M_FROZEN_TIDQ         0x46       /* TID Queue frozen. */
 #define QHSTA_M_SGBACKUP_ERROR      0x47       /* Scatter-Gather backup error */
 
-/*
- * DvcGetPhyAddr() flag arguments
- */
-#define ADV_IS_SCSIQ_FLAG       0x01   /* 'addr' is ASC_SCSI_REQ_Q pointer */
-#define ADV_ASCGETSGLIST_VADDR  0x02   /* 'addr' is AscGetSGList() virtual addr */
-#define ADV_IS_SENSE_FLAG       0x04   /* 'addr' is sense virtual pointer */
-#define ADV_IS_DATA_FLAG        0x08   /* 'addr' is data virtual pointer */
-#define ADV_IS_SGLIST_FLAG      0x10   /* 'addr' is sglist virtual pointer */
-#define ADV_IS_CARRIER_FLAG     0x20   /* 'addr' is ADV_CARR_T pointer */
-
 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
@@ -2220,8 +2215,6 @@ do { \
        (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count))
 #endif /* ADVANSYS_STATS */
 
-#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
-
 /* If the result wraps when calculating tenths, return 0. */
 #define ASC_TENTHS(num, den) \
     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
@@ -2285,7 +2278,7 @@ do { \
 #define ASC_DBG(lvl, format, arg...) {                                 \
        if (asc_dbglvl >= (lvl))                                        \
                printk(KERN_DEBUG "%s: %s: " format, DRV_NAME,          \
-                       __FUNCTION__ , ## arg);                         \
+                       __func__ , ## arg);                             \
 }
 
 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
@@ -2353,46 +2346,13 @@ struct asc_stats {
        ADV_DCNT exe_error;     /* # ASC_ERROR returns. */
        ADV_DCNT exe_unknown;   /* # unknown returns. */
        /* Data Transfer Statistics */
-       ADV_DCNT cont_cnt;      /* # non-scatter-gather I/O requests received */
-       ADV_DCNT cont_xfer;     /* # contiguous transfer 512-bytes */
-       ADV_DCNT sg_cnt;        /* # scatter-gather I/O requests received */
-       ADV_DCNT sg_elem;       /* # scatter-gather elements */
-       ADV_DCNT sg_xfer;       /* # scatter-gather transfer 512-bytes */
+       ADV_DCNT xfer_cnt;      /* # I/O requests received */
+       ADV_DCNT xfer_elem;     /* # scatter-gather elements */
+       ADV_DCNT xfer_sect;     /* # 512-byte blocks */
 };
 #endif /* ADVANSYS_STATS */
 
 /*
- * Adv Library Request Structures
- *
- * The following two structures are used to process Wide Board requests.
- *
- * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
- * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
- * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
- * Mid-Level SCSI request structure.
- *
- * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
- * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
- * up to 255 scatter-gather elements may be used per request or
- * ADV_SCSI_REQ_Q.
- *
- * Both structures must be 32 byte aligned.
- */
-typedef struct adv_sgblk {
-       ADV_SG_BLOCK sg_block;  /* Sgblock structure. */
-       uchar align[32];        /* Sgblock structure padding. */
-       struct adv_sgblk *next_sgblkp;  /* Next scatter-gather structure. */
-} adv_sgblk_t;
-
-typedef struct adv_req {
-       ADV_SCSI_REQ_Q scsi_req_q;      /* Adv Library request structure. */
-       uchar align[32];        /* Request structure padding. */
-       struct scsi_cmnd *cmndp;        /* Mid-Level SCSI command pointer. */
-       adv_sgblk_t *sgblkp;    /* Adv Library scatter-gather pointer. */
-       struct adv_req *next_reqp;      /* Next Request Structure. */
-} adv_req_t;
-
-/*
  * Structure allocated for each board.
  *
  * This structure is allocated by scsi_host_alloc() at the end
@@ -2437,8 +2397,6 @@ struct asc_board {
         */
        void __iomem *ioremap_addr;     /* I/O Memory remap address. */
        ushort ioport;          /* I/O Port address. */
-       ADV_CARR_T *carrp;      /* ADV_CARR_T memory block. */
-       adv_req_t *orig_reqp;   /* adv_req_t memory block. */
        adv_req_t *adv_reqp;    /* Request structures. */
        adv_sgblk_t *adv_sgblkp;        /* Scatter-gather structures. */
        ushort bios_signature;  /* BIOS Signature. */
@@ -2447,13 +2405,12 @@ struct asc_board {
        ushort bios_codelen;    /* BIOS Code Segment Length. */
 };
 
+#define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \
+                                                       dvc_var.asc_dvc_var)
 #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \
                                                        dvc_var.adv_dvc_var)
 #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
 
-/* Overrun buffer used by all narrow boards. */
-static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
-
 #ifdef ADVANSYS_DEBUG
 static int asc_dbglvl = 3;
 
@@ -2508,8 +2465,8 @@ static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
                "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed,
                h->isa_dma_channel, h->chip_version);
 
-       printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n",
-               h->mcode_date, h->mcode_version, h->overrun_buf);
+       printk(" mcode_date 0x%x, mcode_version %d\n",
+               h->mcode_date, h->mcode_version);
 }
 
 /*
@@ -2570,7 +2527,7 @@ static void asc_prt_scsi_host(struct Scsi_Host *s)
 {
        struct asc_board *boardp = shost_priv(s);
 
-       printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id);
+       printk("Scsi_Host at addr 0x%p, device %s\n", s, dev_name(boardp->dev));
        printk(" host_busy %u, host_no %d, last_reset %d,\n",
               s->host_busy, s->host_no, (unsigned)s->last_reset);
 
@@ -2782,6 +2739,59 @@ static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
 #endif /* ADVANSYS_DEBUG */
 
 /*
+ * The advansys chip/microcode contains a 32-bit identifier for each command
+ * known as the 'srb'.  I don't know what it stands for.  The driver used
+ * to encode the scsi_cmnd pointer by calling virt_to_bus and retrieve it
+ * with bus_to_virt.  Now the driver keeps a per-host map of integers to
+ * pointers.  It auto-expands when full, unless it can't allocate memory.
+ * Note that an srb of 0 is treated specially by the chip/firmware, hence
+ * the return of i+1 in this routine, and the corresponding subtraction in
+ * the inverse routine.
+ */
+#define BAD_SRB 0
+static u32 advansys_ptr_to_srb(struct asc_dvc_var *asc_dvc, void *ptr)
+{
+       int i;
+       void **new_ptr;
+
+       for (i = 0; i < asc_dvc->ptr_map_count; i++) {
+               if (!asc_dvc->ptr_map[i])
+                       goto out;
+       }
+
+       if (asc_dvc->ptr_map_count == 0)
+               asc_dvc->ptr_map_count = 1;
+       else
+               asc_dvc->ptr_map_count *= 2;
+
+       new_ptr = krealloc(asc_dvc->ptr_map,
+                       asc_dvc->ptr_map_count * sizeof(void *), GFP_ATOMIC);
+       if (!new_ptr)
+               return BAD_SRB;
+       asc_dvc->ptr_map = new_ptr;
+ out:
+       ASC_DBG(3, "Putting ptr %p into array offset %d\n", ptr, i);
+       asc_dvc->ptr_map[i] = ptr;
+       return i + 1;
+}
+
+static void * advansys_srb_to_ptr(struct asc_dvc_var *asc_dvc, u32 srb)
+{
+       void *ptr;
+
+       srb--;
+       if (srb >= asc_dvc->ptr_map_count) {
+               printk("advansys: bad SRB %u, max %u\n", srb,
+                                                       asc_dvc->ptr_map_count);
+               return NULL;
+       }
+       ptr = asc_dvc->ptr_map[srb];
+       asc_dvc->ptr_map[srb] = NULL;
+       ASC_DBG(3, "Returning ptr %p from array offset %d\n", ptr, srb);
+       return ptr;
+}
+
+/*
  * advansys_info()
  *
  * Return suitable for printing on the console with the argument
@@ -4087,57 +4097,32 @@ static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
        /*
         * Display data transfer statistics.
         */
-       if (s->cont_cnt > 0) {
-               len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
-               ASC_PRT_NEXT();
-
-               len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
-                                  s->cont_xfer / 2,
-                                  ASC_TENTHS(s->cont_xfer, 2));
-               ASC_PRT_NEXT();
-
-               /* Contiguous transfer average size */
-               len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
-                                  (s->cont_xfer / 2) / s->cont_cnt,
-                                  ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
-               ASC_PRT_NEXT();
-       }
-
-       if (s->sg_cnt > 0) {
-
-               len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
-                                  s->sg_cnt, s->sg_elem);
+       if (s->xfer_cnt > 0) {
+               len = asc_prt_line(cp, leftlen, " xfer_cnt %lu, xfer_elem %lu, ",
+                                  s->xfer_cnt, s->xfer_elem);
                ASC_PRT_NEXT();
 
-               len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
-                                  s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
+               len = asc_prt_line(cp, leftlen, "xfer_bytes %lu.%01lu kb\n",
+                                  s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2));
                ASC_PRT_NEXT();
 
                /* Scatter gather transfer statistics */
                len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
-                                  s->sg_elem / s->sg_cnt,
-                                  ASC_TENTHS(s->sg_elem, s->sg_cnt));
+                                  s->xfer_elem / s->xfer_cnt,
+                                  ASC_TENTHS(s->xfer_elem, s->xfer_cnt));
                ASC_PRT_NEXT();
 
                len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
-                                  (s->sg_xfer / 2) / s->sg_elem,
-                                  ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
+                                  (s->xfer_sect / 2) / s->xfer_elem,
+                                  ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem));
                ASC_PRT_NEXT();
 
                len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
-                                  (s->sg_xfer / 2) / s->sg_cnt,
-                                  ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
+                                  (s->xfer_sect / 2) / s->xfer_cnt,
+                                  ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt));
                ASC_PRT_NEXT();
        }
 
-       /*
-        * Display request queuing statistics.
-        */
-       len = asc_prt_line(cp, leftlen,
-                          " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
-                          HZ);
-       ASC_PRT_NEXT();
-
        return totlen;
 }
 #endif /* ADVANSYS_STATS */
@@ -4331,18 +4316,8 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
 
 static void asc_scsi_done(struct scsi_cmnd *scp)
 {
-       struct asc_board *boardp = shost_priv(scp->device->host);
-
-       if (scp->use_sg)
-               dma_unmap_sg(boardp->dev,
-                            (struct scatterlist *)scp->request_buffer,
-                            scp->use_sg, scp->sc_data_direction);
-       else if (scp->request_bufflen)
-               dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
-                                scp->request_bufflen, scp->sc_data_direction);
-
+       scsi_dma_unmap(scp);
        ASC_STATS(scp->device->host, done);
-
        scp->scsi_done(scp);
 }
 
@@ -6341,6 +6316,7 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        PortAddr iop_base;
        ASC_PADDR phy_addr;
        ASC_DCNT phy_size;
+       struct asc_board *board = asc_dvc_to_board(asc_dvc);
 
        iop_base = asc_dvc->iop_base;
        warn_code = 0;
@@ -6355,12 +6331,14 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
                         ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
 
-       /* Align overrun buffer on an 8 byte boundary. */
-       phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
-       phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
+       /* Ensure overrun buffer is aligned on an 8 byte boundary. */
+       BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
+       asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
+                                       ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+       phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
                                 (uchar *)&phy_addr, 1);
-       phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
+       phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE);
        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
                                 (uchar *)&phy_size, 1);
 
@@ -6461,7 +6439,7 @@ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
                        i += 2;
                        len += 2;
                } else {
-                       unsigned char off = buf[i] * 2;
+                       unsigned int off = buf[i] * 2;
                        unsigned short word = (buf[off + 1] << 8) | buf[off];
                        AdvWriteWordAutoIncLram(iop_base, word);
                        len += 2;
@@ -6489,37 +6467,12 @@ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
        return 0;
 }
 
-/*
- * DvcGetPhyAddr()
- *
- * Return the physical address of 'vaddr' and set '*lenp' to the
- * number of physically contiguous bytes that follow 'vaddr'.
- * 'flag' indicates the type of structure whose physical address
- * is being translated.
- *
- * Note: Because Linux currently doesn't page the kernel and all
- * kernel buffers are physically contiguous, leave '*lenp' unchanged.
- */
-ADV_PADDR
-DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
-             uchar *vaddr, ADV_SDCNT *lenp, int flag)
-{
-       ADV_PADDR paddr = virt_to_bus(vaddr);
-
-       ASC_DBG(4, "vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n",
-                vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr);
-
-       return paddr;
-}
-
 static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
 {
        ADV_CARR_T *carrp;
        ADV_SDCNT buf_size;
        ADV_PADDR carr_paddr;
 
-       BUG_ON(!asc_dvc->carrier_buf);
-
        carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
        asc_dvc->carr_freelist = NULL;
        if (carrp == asc_dvc->carrier_buf) {
@@ -6530,24 +6483,10 @@ static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc)
 
        do {
                /* Get physical address of the carrier 'carrp'. */
-               ADV_DCNT contig_len = sizeof(ADV_CARR_T);
-               carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL,
-                                                      (uchar *)carrp,
-                                                      (ADV_SDCNT *)&contig_len,
-                                                      ADV_IS_CARRIER_FLAG));
+               carr_paddr = cpu_to_le32(virt_to_bus(carrp));
 
                buf_size -= sizeof(ADV_CARR_T);
 
-               /*
-                * If the current carrier is not physically contiguous, then
-                * maybe there was a page crossing. Try the next carrier
-                * aligned start address.
-                */
-               if (contig_len < sizeof(ADV_CARR_T)) {
-                       carrp++;
-                       continue;
-               }
-
                carrp->carr_pa = carr_paddr;
                carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
 
@@ -8279,11 +8218,11 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
                 * then return the number of underrun bytes.
                 */
                resid_cnt = le32_to_cpu(scsiqp->data_cnt);
-               if (scp->request_bufflen != 0 && resid_cnt != 0 &&
-                   resid_cnt <= scp->request_bufflen) {
+               if (scsi_bufflen(scp) != 0 && resid_cnt != 0 &&
+                   resid_cnt <= scsi_bufflen(scp)) {
                        ASC_DBG(1, "underrun condition %lu bytes\n",
                                 (ulong)resid_cnt);
-                       scp->resid = resid_cnt;
+                       scsi_set_resid(scp, resid_cnt);
                }
                break;
 
@@ -8294,7 +8233,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
                        if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
                                ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
                                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
-                                                 sizeof(scp->sense_buffer));
+                                                 SCSI_SENSE_BUFFERSIZE);
                                /*
                                 * Note: The 'status_byte()' macro used by
                                 * target drivers defined in scsi.h shifts the
@@ -9183,17 +9122,10 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
        ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep);
        ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
 
-       /*
-        * Get the struct scsi_cmnd structure and Scsi_Host structure for the
-        * command that has been completed.
-        */
-       scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
-       ASC_DBG(1, "scp 0x%p\n", scp);
-
-       if (scp == NULL) {
-               ASC_PRINT("asc_isr_callback: scp is NULL\n");
+       scp = advansys_srb_to_ptr(asc_dvc_varp, qdonep->d2.srb_ptr);
+       if (!scp)
                return;
-       }
+
        ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
 
        shost = scp->device->host;
@@ -9203,6 +9135,8 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
        boardp = shost_priv(shost);
        BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var);
 
+       dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
+                        SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
        /*
         * 'qdonep' contains the command's ending status.
         */
@@ -9217,11 +9151,11 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
                 * If there was no error and an underrun condition, then
                 * return the number of underrun bytes.
                 */
-               if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
-                   qdonep->remain_bytes <= scp->request_bufflen) {
+               if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 &&
+                   qdonep->remain_bytes <= scsi_bufflen(scp)) {
                        ASC_DBG(1, "underrun condition %u bytes\n",
                                 (unsigned)qdonep->remain_bytes);
-                       scp->resid = qdonep->remain_bytes;
+                       scsi_set_resid(scp, qdonep->remain_bytes);
                }
                break;
 
@@ -9232,7 +9166,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
                        if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
                                ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
                                ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
-                                                 sizeof(scp->sense_buffer));
+                                                 SCSI_SENSE_BUFFERSIZE);
                                /*
                                 * Note: The 'status_byte()' macro used by
                                 * target drivers defined in scsi.h shifts the
@@ -9943,15 +9877,32 @@ static int advansys_slave_configure(struct scsi_device *sdev)
        return 0;
 }
 
+static __le32 advansys_get_sense_buffer_dma(struct scsi_cmnd *scp)
+{
+       struct asc_board *board = shost_priv(scp->device->host);
+       scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer,
+                                            SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
+       dma_cache_sync(board->dev, scp->sense_buffer,
+                      SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
+       return cpu_to_le32(scp->SCp.dma_handle);
+}
+
 static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
                        struct asc_scsi_q *asc_scsi_q)
 {
+       struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var;
+       int use_sg;
+
        memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
 
        /*
         * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
         */
-       asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
+       asc_scsi_q->q2.srb_ptr = advansys_ptr_to_srb(asc_dvc, scp);
+       if (asc_scsi_q->q2.srb_ptr == BAD_SRB) {
+               scp->result = HOST_BYTE(DID_SOFT_ERROR);
+               return ASC_ERROR;
+       }
 
        /*
         * Build the ASC_SCSI_Q request.
@@ -9962,9 +9913,8 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
        asc_scsi_q->q1.target_lun = scp->device->lun;
        asc_scsi_q->q2.target_ix =
            ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
-       asc_scsi_q->q1.sense_addr =
-           cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
-       asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
+       asc_scsi_q->q1.sense_addr = advansys_get_sense_buffer_dma(scp);
+       asc_scsi_q->q1.sense_len = SCSI_SENSE_BUFFERSIZE;
 
        /*
         * If there are any outstanding requests for the current target,
@@ -9977,62 +9927,33 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
         * started request.
         *
         */
-       if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
+       if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) &&
            (boardp->reqcnt[scp->device->id] % 255) == 0) {
                asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
        } else {
                asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
        }
 
-       /*
-        * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
-        * buffer command.
-        */
-       if (scp->use_sg == 0) {
-               /*
-                * CDB request of single contiguous buffer.
-                */
-               ASC_STATS(scp->device->host, cont_cnt);
-               scp->SCp.dma_handle = scp->request_bufflen ?
-                   dma_map_single(boardp->dev, scp->request_buffer,
-                                  scp->request_bufflen,
-                                  scp->sc_data_direction) : 0;
-               asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
-               asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen);
-               ASC_STATS_ADD(scp->device->host, cont_xfer,
-                             ASC_CEILING(scp->request_bufflen, 512));
-               asc_scsi_q->q1.sg_queue_cnt = 0;
-               asc_scsi_q->sg_head = NULL;
-       } else {
-               /*
-                * CDB scatter-gather request list.
-                */
+       /* Build ASC_SCSI_Q */
+       use_sg = scsi_dma_map(scp);
+       if (use_sg != 0) {
                int sgcnt;
-               int use_sg;
                struct scatterlist *slp;
                struct asc_sg_head *asc_sg_head;
 
-               slp = (struct scatterlist *)scp->request_buffer;
-               use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
-                                   scp->sc_data_direction);
-
                if (use_sg > scp->device->host->sg_tablesize) {
                        scmd_printk(KERN_ERR, scp, "use_sg %d > "
                                "sg_tablesize %d\n", use_sg,
                                scp->device->host->sg_tablesize);
-                       dma_unmap_sg(boardp->dev, slp, scp->use_sg,
-                                    scp->sc_data_direction);
+                       scsi_dma_unmap(scp);
                        scp->result = HOST_BYTE(DID_ERROR);
                        return ASC_ERROR;
                }
 
-               ASC_STATS(scp->device->host, sg_cnt);
-
                asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
                        use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
                if (!asc_sg_head) {
-                       dma_unmap_sg(boardp->dev, slp, scp->use_sg,
-                                    scp->sc_data_direction);
+                       scsi_dma_unmap(scp);
                        scp->result = HOST_BYTE(DID_SOFT_ERROR);
                        return ASC_ERROR;
                }
@@ -10043,22 +9964,24 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
                asc_scsi_q->q1.data_addr = 0;
                /* This is a byte value, otherwise it would need to be swapped. */
                asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
-               ASC_STATS_ADD(scp->device->host, sg_elem,
+               ASC_STATS_ADD(scp->device->host, xfer_elem,
                              asc_sg_head->entry_cnt);
 
                /*
                 * Convert scatter-gather list into ASC_SG_HEAD list.
                 */
-               for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
+               scsi_for_each_sg(scp, slp, use_sg, sgcnt) {
                        asc_sg_head->sg_list[sgcnt].addr =
                            cpu_to_le32(sg_dma_address(slp));
                        asc_sg_head->sg_list[sgcnt].bytes =
                            cpu_to_le32(sg_dma_len(slp));
-                       ASC_STATS_ADD(scp->device->host, sg_xfer,
-                                     ASC_CEILING(sg_dma_len(slp), 512));
+                       ASC_STATS_ADD(scp->device->host, xfer_sect,
+                                     DIV_ROUND_UP(sg_dma_len(slp), 512));
                }
        }
 
+       ASC_STATS(scp->device->host, xfer_cnt);
+
        ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q);
        ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
 
@@ -10090,7 +10013,7 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
        int i;
 
        scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
-       slp = (struct scatterlist *)scp->request_buffer;
+       slp = scsi_sglist(scp);
        sg_elem_cnt = use_sg;
        prev_sg_block = NULL;
        reqp->sgblkp = NULL;
@@ -10162,8 +10085,8 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
                                        cpu_to_le32(sg_dma_address(slp));
                        sg_block->sg_list[i].sg_count =
                                        cpu_to_le32(sg_dma_len(slp));
-                       ASC_STATS_ADD(scp->device->host, sg_xfer,
-                                     ASC_CEILING(sg_dma_len(slp), 512));
+                       ASC_STATS_ADD(scp->device->host, xfer_sect,
+                                     DIV_ROUND_UP(sg_dma_len(slp), 512));
 
                        if (--sg_elem_cnt == 0) {       /* Last ADV_SG_BLOCK and scatter-gather entry. */
                                sg_block->sg_cnt = i + 1;
@@ -10195,6 +10118,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
        ADV_SCSI_REQ_Q *scsiqp;
        int i;
        int ret;
+       int use_sg;
 
        /*
         * Allocate an adv_req_t structure from the board to execute
@@ -10223,7 +10147,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
        /*
         * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
         */
-       scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
+       scsiqp->srb_ptr = ADV_VADDR_TO_U32(reqp);
 
        /*
         * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
@@ -10249,56 +10173,26 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
        scsiqp->target_lun = scp->device->lun;
 
        scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
-       scsiqp->sense_len = sizeof(scp->sense_buffer);
-
-       /*
-        * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
-        * buffer command.
-        */
+       scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
 
-       scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
-       scsiqp->vdata_addr = scp->request_buffer;
-       scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
+       /* Build ADV_SCSI_REQ_Q */
 
-       if (scp->use_sg == 0) {
-               /*
-                * CDB request of single contiguous buffer.
-                */
+       use_sg = scsi_dma_map(scp);
+       if (use_sg == 0) {
+               /* Zero-length transfer */
                reqp->sgblkp = NULL;
-               scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
-               if (scp->request_bufflen) {
-                       scsiqp->vdata_addr = scp->request_buffer;
-                       scp->SCp.dma_handle =
-                           dma_map_single(boardp->dev, scp->request_buffer,
-                                          scp->request_bufflen,
-                                          scp->sc_data_direction);
-               } else {
-                       scsiqp->vdata_addr = NULL;
-                       scp->SCp.dma_handle = 0;
-               }
-               scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
+               scsiqp->data_cnt = 0;
+               scsiqp->vdata_addr = NULL;
+
+               scsiqp->data_addr = 0;
                scsiqp->sg_list_ptr = NULL;
                scsiqp->sg_real_addr = 0;
-               ASC_STATS(scp->device->host, cont_cnt);
-               ASC_STATS_ADD(scp->device->host, cont_xfer,
-                             ASC_CEILING(scp->request_bufflen, 512));
        } else {
-               /*
-                * CDB scatter-gather request list.
-                */
-               struct scatterlist *slp;
-               int use_sg;
-
-               slp = (struct scatterlist *)scp->request_buffer;
-               use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
-                                   scp->sc_data_direction);
-
                if (use_sg > ADV_MAX_SG_LIST) {
                        scmd_printk(KERN_ERR, scp, "use_sg %d > "
                                   "ADV_MAX_SG_LIST %d\n", use_sg,
                                   scp->device->host->sg_tablesize);
-                       dma_unmap_sg(boardp->dev, slp, scp->use_sg,
-                                    scp->sc_data_direction);
+                       scsi_dma_unmap(scp);
                        scp->result = HOST_BYTE(DID_ERROR);
 
                        /*
@@ -10311,6 +10205,8 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
                        return ASC_ERROR;
                }
 
+               scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp));
+
                ret = adv_get_sglist(boardp, reqp, scp, use_sg);
                if (ret != ADV_SUCCESS) {
                        /*
@@ -10323,10 +10219,11 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
                        return ret;
                }
 
-               ASC_STATS(scp->device->host, sg_cnt);
-               ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
+               ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg);
        }
 
+       ASC_STATS(scp->device->host, xfer_cnt);
+
        ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
        ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
 
@@ -10923,7 +10820,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
 {
        AdvPortAddr iop_base;
-       ADV_DCNT req_size;
        ADV_PADDR req_paddr;
        ADV_CARR_T *new_carrp;
 
@@ -10961,13 +10857,8 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
         */
        scsiq->a_flag &= ~ADV_SCSIQ_DONE;
 
-       req_size = sizeof(ADV_SCSI_REQ_Q);
-       req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
-                                 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
-
+       req_paddr = virt_to_bus(scsiq);
        BUG_ON(req_paddr & 31);
-       BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q));
-
        /* Wait for assertion before making little-endian */
        req_paddr = cpu_to_le32(req_paddr);
 
@@ -11030,48 +10921,6 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
 
 /*
  * Execute a single 'Scsi_Cmnd'.
- *
- * The function 'done' is called when the request has been completed.
- *
- * Scsi_Cmnd:
- *
- *  host - board controlling device
- *  device - device to send command
- *  target - target of device
- *  lun - lun of device
- *  cmd_len - length of SCSI CDB
- *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
- *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
- *
- *  if (use_sg == 0) {
- *    request_buffer - buffer address for request
- *    request_bufflen - length of request buffer
- *  } else {
- *    request_buffer - pointer to scatterlist structure
- *  }
- *
- *  sense_buffer - sense command buffer
- *
- *  result (4 bytes of an int):
- *    Byte Meaning
- *    0 SCSI Status Byte Code
- *    1 SCSI One Byte Message Code
- *    2 Host Error Code
- *    3 Mid-Level Error Code
- *
- *  host driver fields:
- *    SCp - Scsi_Pointer used for command processing status
- *    scsi_done - used to save caller's done function
- *    host_scribble - used for pointer to another struct scsi_cmnd
- *
- * If this function returns ASC_NOERROR the request will be completed
- * from the interrupt handler.
- *
- * If this function returns ASC_ERROR the host error code has been set,
- * and the called must call asc_scsi_done.
- *
- * If ASC_BUSY is returned the request will be returned to the midlayer
- * and re-tried later.
  */
 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
 {
@@ -12412,7 +12261,7 @@ static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __devinit
+static void __devinit
 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -12479,7 +12328,7 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __devinit
+static void __devinit
 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -12546,7 +12395,7 @@ AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
 /*
  * Write the EEPROM from 'cfg_buf'.
  */
-void __devinit
+static void __devinit
 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
 {
        ushort *wbuf;
@@ -13442,10 +13291,10 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
         * Allocate buffer carrier structures. The total size
         * is about 4 KB, so allocate all at once.
         */
-       board->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
-       ASC_DBG(1, "carrp 0x%p\n", board->carrp);
+       adv_dvc->carrier_buf = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
+       ASC_DBG(1, "carrier_buf 0x%p\n", adv_dvc->carrier_buf);
 
-       if (!board->carrp)
+       if (!adv_dvc->carrier_buf)
                goto kmalloc_failed;
 
        /*
@@ -13466,7 +13315,7 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
        if (!reqp)
                goto kmalloc_failed;
 
-       board->orig_reqp = reqp;
+       adv_dvc->orig_reqp = reqp;
 
        /*
         * Allocate up to ADV_TOT_SG_BLOCK request structures for
@@ -13484,14 +13333,12 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
 
        }
 
-       ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t),
-                (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
+       ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", sg_cnt, sizeof(adv_sgblk_t),
+                sizeof(adv_sgblk_t) * sg_cnt);
 
        if (!board->adv_sgblkp)
                goto kmalloc_failed;
 
-       adv_dvc->carrier_buf = board->carrp;
-
        /*
         * Point 'adv_reqp' to the request structures and
         * link them together.
@@ -13529,15 +13376,16 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost)
        return err_code;
 }
 
-static void advansys_wide_free_mem(struct asc_board *boardp)
+static void advansys_wide_free_mem(struct asc_board *board)
 {
-       kfree(boardp->carrp);
-       boardp->carrp = NULL;
-       kfree(boardp->orig_reqp);
-       boardp->orig_reqp = boardp->adv_reqp = NULL;
-       while (boardp->adv_sgblkp) {
-               adv_sgblk_t *sgp = boardp->adv_sgblkp;
-               boardp->adv_sgblkp = sgp->next_sgblkp;
+       struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var;
+       kfree(adv_dvc->carrier_buf);
+       adv_dvc->carrier_buf = NULL;
+       kfree(adv_dvc->orig_reqp);
+       adv_dvc->orig_reqp = board->adv_reqp = NULL;
+       while (board->adv_sgblkp) {
+               adv_sgblk_t *sgp = board->adv_sgblkp;
+               board->adv_sgblkp = sgp->next_sgblkp;
                kfree(sgp);
        }
 }
@@ -13559,7 +13407,6 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                asc_dvc_varp->bus_type = bus_type;
                asc_dvc_varp->drv_ptr = boardp;
                asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
-               asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
                asc_dvc_varp->iop_base = iop;
        } else {
 #ifdef CONFIG_PCI
@@ -13578,12 +13425,11 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                }
 
                boardp->asc_n_io_port = pci_resource_len(pdev, 1);
-               boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1),
-                                              boardp->asc_n_io_port);
+               boardp->ioremap_addr = pci_ioremap_bar(pdev, 1);
                if (!boardp->ioremap_addr) {
-                       shost_printk(KERN_ERR, shost, "ioremap(%x, %d) "
+                       shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) "
                                        "returned NULL\n",
-                                       pci_resource_start(pdev, 1),
+                                       (long)pci_resource_start(pdev, 1),
                                        boardp->asc_n_io_port);
                        ret = -ENODEV;
                        goto err_shost;
@@ -13986,6 +13832,12 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
         */
        if (ASC_NARROW_BOARD(boardp)) {
                ASC_DBG(2, "AscInitAsc1000Driver()\n");
+
+               asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
+               if (!asc_dvc_varp->overrun_buf) {
+                       ret = -ENOMEM;
+                       goto err_free_wide_mem;
+               }
                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
 
                if (warn_code || asc_dvc_varp->err_code) {
@@ -13993,8 +13845,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                                        "warn 0x%x, error 0x%x\n",
                                        asc_dvc_varp->init_state, warn_code,
                                        asc_dvc_varp->err_code);
-                       if (asc_dvc_varp->err_code)
+                       if (asc_dvc_varp->err_code) {
                                ret = -ENODEV;
+                               kfree(asc_dvc_varp->overrun_buf);
+                       }
                }
        } else {
                if (advansys_wide_init_chip(shost))
@@ -14017,8 +13871,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
        advansys_wide_free_mem(boardp);
        free_irq(boardp->irq, shost);
  err_free_dma:
+#ifdef CONFIG_ISA
        if (shost->dma_channel != NO_ISA_DMA)
                free_dma(shost->dma_channel);
+#endif
  err_free_proc:
        kfree(boardp->prtbuf);
  err_unmap:
@@ -14035,19 +13891,26 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
  */
 static int advansys_release(struct Scsi_Host *shost)
 {
-       struct asc_board *boardp = shost_priv(shost);
+       struct asc_board *board = shost_priv(shost);
        ASC_DBG(1, "begin\n");
        scsi_remove_host(shost);
-       free_irq(boardp->irq, shost);
+       free_irq(board->irq, shost);
+#ifdef CONFIG_ISA
        if (shost->dma_channel != NO_ISA_DMA) {
                ASC_DBG(1, "free_dma()\n");
                free_dma(shost->dma_channel);
        }
-       if (!ASC_NARROW_BOARD(boardp)) {
-               iounmap(boardp->ioremap_addr);
-               advansys_wide_free_mem(boardp);
+#endif
+       if (ASC_NARROW_BOARD(board)) {
+               dma_unmap_single(board->dev,
+                                       board->dvc_var.asc_dvc_var.overrun_dma,
+                                       ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+               kfree(board->dvc_var.asc_dvc_var.overrun_buf);
+       } else {
+               iounmap(board->ioremap_addr);
+               advansys_wide_free_mem(board);
        }
-       kfree(boardp->prtbuf);
+       kfree(board->prtbuf);
        scsi_host_put(shost);
        ASC_DBG(1, "end\n");
        return 0;
@@ -14055,7 +13918,7 @@ static int advansys_release(struct Scsi_Host *shost)
 
 #define ASC_IOADR_TABLE_MAX_IX  11
 
-static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
+static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] = {
        0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
        0x0210, 0x0230, 0x0250, 0x0330
 };