X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=drivers%2Fscsi%2Fadvansys.c;h=38a1ee2eacd86a00b9a8c9fa6595126e63a72b04;hb=8e7657ae0f56c14882e53ffdae8055c2b1624de1;hp=a4091ab8d363d765519ff0efdb3c25adb39026fd;hpb=f092d2290f905b6e9928df6905f2fc9d18b6ae19;p=~andy%2Flinux diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index a4091ab8d36..38a1ee2eacd 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -66,8 +66,7 @@ * 5. check DMA mapping functions for failure * 6. Use scsi_transport_spi * 7. advansys_info is not safe against multiple simultaneous callers - * 8. Kill boardp->id - * 9. Add module_param to override ISA/VLB ioport array + * 8. Add module_param to override ISA/VLB ioport array */ #warning this driver is still not properly converted to the DMA API @@ -91,17 +90,6 @@ #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 @@ -132,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)) @@ -482,34 +470,22 @@ typedef struct asc_risc_sg_list_q { #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20 #define ASC_MAX_INRAM_TAG_QNG 16 #define ASC_IOADR_GAP 0x10 -#define ASC_MAX_SYN_XFER_NO 16 #define ASC_SYN_MAX_OFFSET 0x0F #define ASC_DEF_SDTR_OFFSET 0x0F #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02 -#define SYN_XFER_NS_0 25 -#define SYN_XFER_NS_1 30 -#define SYN_XFER_NS_2 35 -#define SYN_XFER_NS_3 40 -#define SYN_XFER_NS_4 50 -#define SYN_XFER_NS_5 60 -#define SYN_XFER_NS_6 70 -#define SYN_XFER_NS_7 85 -#define SYN_ULTRA_XFER_NS_0 12 -#define SYN_ULTRA_XFER_NS_1 19 -#define SYN_ULTRA_XFER_NS_2 25 -#define SYN_ULTRA_XFER_NS_3 32 -#define SYN_ULTRA_XFER_NS_4 38 -#define SYN_ULTRA_XFER_NS_5 44 -#define SYN_ULTRA_XFER_NS_6 50 -#define SYN_ULTRA_XFER_NS_7 57 -#define SYN_ULTRA_XFER_NS_8 63 -#define SYN_ULTRA_XFER_NS_9 69 -#define SYN_ULTRA_XFER_NS_10 75 -#define SYN_ULTRA_XFER_NS_11 82 -#define SYN_ULTRA_XFER_NS_12 88 -#define SYN_ULTRA_XFER_NS_13 94 -#define SYN_ULTRA_XFER_NS_14 100 -#define SYN_ULTRA_XFER_NS_15 107 +#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 + +/* The narrow chip only supports a limited selection of transfer rates. + * These are encoded in the range 0..7 or 0..15 depending whether the chip + * is Ultra-capable or not. These tables let us convert from one to the other. + */ +static const unsigned char asc_syn_xfer_period[8] = { + 25, 30, 35, 40, 50, 60, 70, 85 +}; + +static const unsigned char asc_syn_ultra_xfer_period[16] = { + 12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107 +}; typedef struct ext_msg { uchar msg_type; @@ -553,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; @@ -573,9 +548,9 @@ typedef struct asc_dvc_cfg { #define ASC_INIT_STATE_WITHOUT_EEP 0x8000 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 -#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 #define ASC_MIN_TAGGED_CMD 7 #define ASC_MAX_SCSI_RESET_WAIT 30 +#define ASC_OVERRUN_BSIZE 64 struct asc_dvc_var; /* Forward Declaration. */ @@ -591,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[ASC_OVERRUN_BSIZE] __aligned(8); + dma_addr_t overrun_dma; uchar scsi_reset_wait; uchar chip_no; char is_in_int; @@ -603,7 +580,7 @@ typedef struct asc_dvc_var { uchar max_dvc_qng[ASC_MAX_TID + 1]; ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1]; ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1]; - uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO]; + const uchar *sdtr_period_tbl; ASC_DVC_CFG *cfg; ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always; char redo_scam; @@ -612,9 +589,11 @@ typedef struct asc_dvc_var { ASC_DCNT max_dma_count; ASC_SCSI_BIT_ID_TYPE no_scam; ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer; + uchar min_sdtr_index; uchar max_sdtr_index; - uchar host_init_sdtr_index; struct asc_board *drv_ptr; + int ptr_map_count; + void **ptr_map; ASC_DCNT uc_break; } ASC_DVC_VAR; @@ -691,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) @@ -897,7 +875,6 @@ typedef struct asc_mc_saved { #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) -#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ]) #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE) #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD) #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION) @@ -998,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) @@ -1808,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)) @@ -1854,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; @@ -1960,6 +1873,83 @@ typedef struct adv_scsi_req_q { uchar pad[2]; /* Pad out to a word boundary. */ } 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 */ @@ -2162,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) @@ -2235,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))) ? \ @@ -2368,45 +2346,12 @@ 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. * @@ -2416,7 +2361,6 @@ typedef struct adv_req { */ struct asc_board { struct device *dev; - int id; /* Board Id */ uint flags; /* Board flags */ unsigned int irq; union { @@ -2453,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. */ @@ -2463,16 +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) -/* Number of boards detected in system. */ -static int asc_board_count; - -/* Overrun buffer used by all narrow boards. */ -static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; - #ifdef ADVANSYS_DEBUG static int asc_dbglvl = 3; @@ -2527,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); } /* @@ -2800,6 +2738,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() * @@ -2848,9 +2839,8 @@ static const char *advansys_info(struct Scsi_Host *shost) } } else { busname = "?"; - ASC_PRINT2("advansys_info: board %d: unknown " - "bus type %d\n", boardp->id, - asc_dvc_varp->bus_type); + shost_printk(KERN_ERR, shost, "unknown bus " + "type %d\n", asc_dvc_varp->bus_type); } sprintf(info, "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", @@ -4107,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)); + 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(); - /* 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); - 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 */ @@ -4351,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); } @@ -4382,7 +4337,6 @@ static void AscSetBank(PortAddr iop_base, uchar bank) val &= ~CC_BANK_ONE; } AscSetChipControl(iop_base, val); - return; } static void AscSetChipIH(PortAddr iop_base, ushort ins_code) @@ -4390,7 +4344,6 @@ static void AscSetChipIH(PortAddr iop_base, ushort ins_code) AscSetBank(iop_base, 1); AscWriteChipIH(iop_base, ins_code); AscSetBank(iop_base, 0); - return; } static int AscStartChip(PortAddr iop_base) @@ -4475,7 +4428,6 @@ static void AscEnableInterrupt(PortAddr iop_base) cfg = AscGetChipCfgLsw(iop_base); AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); - return; } static void AscDisableInterrupt(PortAddr iop_base) @@ -4484,7 +4436,6 @@ static void AscDisableInterrupt(PortAddr iop_base) cfg = AscGetChipCfgLsw(iop_base); AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); - return; } static uchar AscReadLramByte(PortAddr iop_base, ushort addr) @@ -4542,7 +4493,6 @@ static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val) { AscSetChipLramAddr(iop_base, addr); AscSetChipLramData(iop_base, word_val); - return; } static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) @@ -4560,7 +4510,6 @@ static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) word_data |= ((ushort)byte_val & 0x00FF); } AscWriteLramWord(iop_base, addr, word_data); - return; } /* @@ -4588,7 +4537,6 @@ AscMemWordCopyPtrToLram(PortAddr iop_base, outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); } - return; } /* @@ -4608,7 +4556,6 @@ AscMemDWordCopyPtrToLram(PortAddr iop_base, outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */ outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */ } - return; } /* @@ -4630,7 +4577,6 @@ AscMemWordCopyPtrFromLram(PortAddr iop_base, d_buffer[i] = word & 0xff; d_buffer[i + 1] = (word >> 8) & 0xff; } - return; } static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words) @@ -6370,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; @@ -6384,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); @@ -6518,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) { @@ -6559,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)); @@ -8308,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; @@ -8397,8 +8307,6 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) boardp->adv_reqp = reqp; ASC_DBG(1, "done\n"); - - return; } /* @@ -8569,19 +8477,18 @@ static void AscAckInterrupt(PortAddr iop_base) } } AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); - return; } static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time) { - uchar *period_table; + const uchar *period_table; int max_index; int min_index; int i; period_table = asc_dvc->sdtr_period_tbl; max_index = (int)asc_dvc->max_sdtr_index; - min_index = (int)asc_dvc->host_init_sdtr_index; + min_index = (int)asc_dvc->min_sdtr_index; if ((syn_time <= period_table[max_index])) { for (i = min_index; i < (max_index - 1); i++) { if (syn_time <= period_table[i]) { @@ -8630,9 +8537,8 @@ AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset) uchar sdtr_period_ix; sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); - if (sdtr_period_ix > asc_dvc->max_sdtr_index) { + if (sdtr_period_ix > asc_dvc->max_sdtr_index) return 0xFF; - } byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); return byte; } @@ -8743,15 +8649,14 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; } if ((ext_msg.xfer_period < - asc_dvc->sdtr_period_tbl[asc_dvc-> - host_init_sdtr_index]) + asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index]) || (ext_msg.xfer_period > asc_dvc->sdtr_period_tbl[asc_dvc-> max_sdtr_index])) { sdtr_accept = FALSE; ext_msg.xfer_period = asc_dvc->sdtr_period_tbl[asc_dvc-> - host_init_sdtr_index]; + min_sdtr_index]; } if (sdtr_accept) { sdtr_data = @@ -8775,7 +8680,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); } else { if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { - q_cntl &= ~QC_MSG_OUT; asc_dvc->sdtr_done |= target_id; asc_dvc->init_sdtr |= target_id; @@ -8790,7 +8694,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) tid_no); boardp->sdtr_data[tid_no] = sdtr_data; } else { - q_cntl |= QC_MSG_OUT; AscMsgOutSDTR(asc_dvc, ext_msg.xfer_period, @@ -9219,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; @@ -9239,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, + sizeof(scp->sense_buffer), DMA_FROM_DEVICE); /* * 'qdonep' contains the command's ending status. */ @@ -9253,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; @@ -9325,8 +9223,6 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) } asc_scsi_done(scp); - - return; } static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) @@ -9981,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, + sizeof(scp->sense_buffer), DMA_FROM_DEVICE); + dma_cache_sync(board->dev, scp->sense_buffer, + sizeof(scp->sense_buffer), 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. @@ -10000,8 +9913,7 @@ 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_addr = advansys_get_sense_buffer_dma(scp); asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer); /* @@ -10015,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) { - ASC_PRINT3("asc_build_req: board %d: use_sg %d > " - "sg_tablesize %d\n", boardp->id, use_sg, - scp->device->host->sg_tablesize); - dma_unmap_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); + scmd_printk(KERN_ERR, scp, "use_sg %d > " + "sg_tablesize %d\n", use_sg, + scp->device->host->sg_tablesize); + 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; } @@ -10081,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); @@ -10128,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; @@ -10200,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; @@ -10233,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 @@ -10261,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. @@ -10289,54 +10175,24 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, 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. - */ + /* Build ADV_SCSI_REQ_Q */ - 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)); - - 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) { - ASC_PRINT3("adv_build_req: board %d: use_sg %d > " - "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg, + 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); /* @@ -10349,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) { /* @@ -10361,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); @@ -10961,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; @@ -10999,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); @@ -11068,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) { @@ -11174,14 +10985,14 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() " - "ASC_ERROR, err_code 0x%x\n", boardp->id, err_code); + scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, " + "err_code 0x%x\n", err_code); ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); break; default: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() " - "unknown, err_code 0x%x\n", boardp->id, err_code); + scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, " + "err_code 0x%x\n", err_code); ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); break; @@ -11314,7 +11125,6 @@ static void __devinit AscEnableIsaDma(uchar dma_channel) outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4))); outp(0x00D4, (ushort)(dma_channel - 4)); } - return; } #endif /* CONFIG_ISA */ @@ -11428,7 +11238,7 @@ static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) asc_dvc->queue_full_or_busy = 0; asc_dvc->redo_scam = 0; asc_dvc->res2 = 0; - asc_dvc->host_init_sdtr_index = 0; + asc_dvc->min_sdtr_index = 0; asc_dvc->cfg->can_tagged_qng = 0; asc_dvc->cfg->cmd_qng_enabled = 0; asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; @@ -11442,34 +11252,12 @@ static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); asc_dvc->cfg->chip_version = chip_version; - asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; - asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1; - asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2; - asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3; - asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4; - asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5; - asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6; - asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7; + asc_dvc->sdtr_period_tbl = asc_syn_xfer_period; asc_dvc->max_sdtr_index = 7; if ((asc_dvc->bus_type & ASC_IS_PCI) && (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { asc_dvc->bus_type = ASC_IS_PCI_ULTRA; - asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0; - asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1; - asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2; - asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3; - asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4; - asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5; - asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6; - asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7; - asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8; - asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9; - asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10; - asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11; - asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12; - asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13; - asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14; - asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15; + asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period; asc_dvc->max_sdtr_index = 15; if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) { AscSetExtraControl(iop_base, @@ -11613,7 +11401,6 @@ static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc) static void __devinit AscWaitEEPWrite(void) { mdelay(20); - return; } static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) @@ -11911,7 +11698,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { - asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; + asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; } for (i = 0; i <= ASC_MAX_TID; i++) { @@ -11919,7 +11706,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; asc_dvc->cfg->sdtr_period_offset[i] = (uchar)(ASC_DEF_SDTR_OFFSET | - (asc_dvc->host_init_sdtr_index << 4)); + (asc_dvc->min_sdtr_index << 4)); } eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); if (write_eep) { @@ -11936,9 +11723,10 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static int __devinit AscInitGetConfig(struct asc_board *boardp) +static int __devinit AscInitGetConfig(struct Scsi_Host *shost) { - ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; + struct asc_board *board = shost_priv(shost); + ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var; unsigned short warn_code = 0; asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; @@ -11959,43 +11747,40 @@ static int __devinit AscInitGetConfig(struct asc_board *boardp) case 0: /* No error */ break; case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1("AscInitGetConfig: board %d: I/O port address " - "modified\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port address " + "modified\n"); break; case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment " - "switch enabled\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port increment switch " + "enabled\n"); break; case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum " - "error\n", boardp->id); + shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n"); break; case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n", - boardp->id); + shost_printk(KERN_WARNING, shost, "IRQ modified\n"); break; case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled " - "w/o disconnects\n", boardp->id); + shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o " + "disconnects\n"); break; default: - ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: " - "0x%x\n", boardp->id, warn_code); + shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n", + warn_code); break; } - if (asc_dvc->err_code != 0) { - ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, " - "err_code 0x%x\n", boardp->id, asc_dvc->init_state, - asc_dvc->err_code); - } + if (asc_dvc->err_code != 0) + shost_printk(KERN_ERR, shost, "error 0x%x at init_state " + "0x%x\n", asc_dvc->err_code, asc_dvc->init_state); return asc_dvc->err_code; } -static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct asc_board *boardp) +static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) { - ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; + struct asc_board *board = shost_priv(shost); + ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var; PortAddr iop_base = asc_dvc->iop_base; unsigned short cfg_msw; unsigned short warn_code = 0; @@ -12060,37 +11845,32 @@ static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct asc_board *bo case 0: /* No error. */ break; case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1("AscInitSetConfig: board %d: I/O port address " - "modified\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port address " + "modified\n"); break; case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment " - "switch enabled\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port increment switch " + "enabled\n"); break; case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum " - "error\n", boardp->id); + shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n"); break; case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n", - boardp->id); + shost_printk(KERN_WARNING, shost, "IRQ modified\n"); break; case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o " - "disconnects\n", - boardp->id); + shost_printk(KERN_WARNING, shost, "tag queuing w/o " + "disconnects\n"); break; default: - ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: " - "0x%x\n", boardp->id, warn_code); + shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n", + warn_code); break; } - if (asc_dvc->err_code != 0) { - ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, " - "err_code 0x%x\n", boardp->id, asc_dvc->init_state, - asc_dvc->err_code); - } + if (asc_dvc->err_code != 0) + shost_printk(KERN_ERR, shost, "error 0x%x at init_state " + "0x%x\n", asc_dvc->err_code, asc_dvc->init_state); return asc_dvc->err_code; } @@ -13390,9 +13170,10 @@ static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) * then 0 is returned. */ static int __devinit -AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp) +AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) { - ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var; + struct asc_board *board = shost_priv(shost); + ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var; unsigned short warn_code = 0; AdvPortAddr iop_base = asc_dvc->iop_base; u16 cmd; @@ -13458,15 +13239,12 @@ AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp) warn_code |= status; } - if (warn_code != 0) { - ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n", - boardp->id, warn_code); - } + if (warn_code != 0) + shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code); - if (asc_dvc->err_code) { - ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n", - boardp->id, asc_dvc->err_code); - } + if (asc_dvc->err_code) + shost_printk(KERN_ERR, shost, "error code 0x%x\n", + asc_dvc->err_code); return asc_dvc->err_code; } @@ -13499,9 +13277,10 @@ static struct scsi_host_template advansys_template = { .use_clustering = ENABLE_CLUSTERING, }; -static int __devinit -advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) +static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) { + struct asc_board *board = shost_priv(shost); + struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var; int req_cnt = 0; adv_req_t *reqp = NULL; int sg_cnt = 0; @@ -13512,10 +13291,10 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) * Allocate buffer carrier structures. The total size * is about 4 KB, so allocate all at once. */ - boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); - ASC_DBG(1, "carrp 0x%p\n", boardp->carrp); + adv_dvc->carrier_buf = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); + ASC_DBG(1, "carrier_buf 0x%p\n", adv_dvc->carrier_buf); - if (!boardp->carrp) + if (!adv_dvc->carrier_buf) goto kmalloc_failed; /* @@ -13523,7 +13302,7 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) * board. The total size is about 16 KB, so allocate all at once. * If the allocation fails decrement and try again. */ - for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) { + for (req_cnt = adv_dvc->max_host_qng; req_cnt > 0; req_cnt--) { reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL); ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt, @@ -13536,32 +13315,30 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) if (!reqp) goto kmalloc_failed; - boardp->orig_reqp = reqp; + adv_dvc->orig_reqp = reqp; /* * Allocate up to ADV_TOT_SG_BLOCK request structures for * the Wide board. Each structure is about 136 bytes. */ - boardp->adv_sgblkp = NULL; + board->adv_sgblkp = NULL; for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL); if (!sgp) break; - sgp->next_sgblkp = boardp->adv_sgblkp; - boardp->adv_sgblkp = sgp; + sgp->next_sgblkp = board->adv_sgblkp; + board->adv_sgblkp = sgp; } - 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 (!boardp->adv_sgblkp) + if (!board->adv_sgblkp) goto kmalloc_failed; - adv_dvc_varp->carrier_buf = boardp->carrp; - /* * Point 'adv_reqp' to the request structures and * link them together. @@ -13571,44 +13348,44 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) for (; req_cnt > 0; req_cnt--) { reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; } - boardp->adv_reqp = &reqp[0]; + board->adv_reqp = &reqp[0]; - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + if (adv_dvc->chip_type == ADV_CHIP_ASC3550) { ASC_DBG(2, "AdvInitAsc3550Driver()\n"); - warn_code = AdvInitAsc3550Driver(adv_dvc_varp); - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + warn_code = AdvInitAsc3550Driver(adv_dvc); + } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) { ASC_DBG(2, "AdvInitAsc38C0800Driver()\n"); - warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp); + warn_code = AdvInitAsc38C0800Driver(adv_dvc); } else { ASC_DBG(2, "AdvInitAsc38C1600Driver()\n"); - warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp); + warn_code = AdvInitAsc38C1600Driver(adv_dvc); } - err_code = adv_dvc_varp->err_code; + err_code = adv_dvc->err_code; if (warn_code || err_code) { - ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x," - " error 0x%x\n", boardp->id, warn_code, err_code); + shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error " + "0x%x\n", warn_code, err_code); } goto exit; kmalloc_failed: - ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() " - "failed\n", boardp->id); + shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n"); err_code = ADV_ERROR; exit: 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); } } @@ -13622,7 +13399,6 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, ADV_DVC_VAR *adv_dvc_varp = NULL; int share_irq, warn_code, ret; - boardp->id = asc_board_count++; pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL; if (ASC_NARROW_BOARD(boardp)) { @@ -13631,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 @@ -13653,10 +13428,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1), boardp->asc_n_io_port); if (!boardp->ioremap_addr) { - ASC_PRINT3 - ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", - boardp->id, pci_resource_start(pdev, 1), - boardp->asc_n_io_port); + shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) " + "returned NULL\n", + (long)pci_resource_start(pdev, 1), + boardp->asc_n_io_port); ret = -ENODEV; goto err_shost; } @@ -13682,8 +13457,8 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, */ boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL); if (!boardp->prtbuf) { - ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) " - "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE); + shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n", + ASC_PRTBUF_SIZE); ret = -ENOMEM; goto err_unmap; } @@ -13716,9 +13491,8 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, break; #endif /* CONFIG_PCI */ default: - ASC_PRINT2 - ("advansys_board_found: board %d: unknown adapter type: %d\n", - boardp->id, asc_dvc_varp->bus_type); + shost_printk(KERN_ERR, shost, "unknown adapter type: " + "%d\n", asc_dvc_varp->bus_type); shost->unchecked_isa_dma = TRUE; share_irq = 0; break; @@ -13731,7 +13505,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, * referenced only use the bit-wise AND operator "&". */ ASC_DBG(2, "AscInitGetConfig()\n"); - ret = AscInitGetConfig(boardp) ? -ENODEV : 0; + ret = AscInitGetConfig(shost) ? -ENODEV : 0; } else { #ifdef CONFIG_PCI /* @@ -13742,7 +13516,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, share_irq = IRQF_SHARED; ASC_DBG(2, "AdvInitGetConfig()\n"); - ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0; + ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0; #endif /* CONFIG_PCI */ } @@ -13790,7 +13564,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, * Modify board configuration. */ ASC_DBG(2, "AscInitSetConfig()\n"); - ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0; + ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0; if (ret) goto err_free_proc; } else { @@ -14024,9 +13798,9 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; ret = request_dma(shost->dma_channel, DRV_NAME); if (ret) { - ASC_PRINT3 - ("advansys_board_found: board %d: request_dma() %d failed %d\n", - boardp->id, shost->dma_channel, ret); + shost_printk(KERN_ERR, shost, "request_dma() " + "%d failed %d\n", + shost->dma_channel, ret); goto err_free_proc; } AscEnableIsaDma(shost->dma_channel); @@ -14042,17 +13816,14 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, if (ret) { if (ret == -EBUSY) { - ASC_PRINT2 - ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n", - boardp->id, boardp->irq); + shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " + "already in use\n", boardp->irq); } else if (ret == -EINVAL) { - ASC_PRINT2 - ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n", - boardp->id, boardp->irq); + shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " + "not valid\n", boardp->irq); } else { - ASC_PRINT3 - ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", - boardp->id, boardp->irq, ret); + shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " + "failed with %d\n", boardp->irq, ret); } goto err_free_dma; } @@ -14065,15 +13836,15 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, warn_code = AscInitAsc1000Driver(asc_dvc_varp); if (warn_code || asc_dvc_varp->err_code) { - ASC_PRINT4("advansys_board_found: board %d error: " - "init_state 0x%x, warn 0x%x, error 0x%x\n", - boardp->id, asc_dvc_varp->init_state, - warn_code, asc_dvc_varp->err_code); + shost_printk(KERN_ERR, shost, "error: init_state 0x%x, " + "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) ret = -ENODEV; } } else { - if (advansys_wide_init_chip(boardp, adv_dvc_varp)) + if (advansys_wide_init_chip(shost)) ret = -ENODEV; } @@ -14111,19 +13882,23 @@ 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); 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); + if (ASC_NARROW_BOARD(board)) { + dma_unmap_single(board->dev, + board->dvc_var.asc_dvc_var.overrun_dma, + ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); + } 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; @@ -14131,7 +13906,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 };