#define ASC_MAX_CDB_LEN 12
#define ASC_SCSI_RESET_HOLD_TIME_US 60
-#define ADV_INQ_CLOCKING_ST_ONLY 0x0
-#define ADV_INQ_CLOCKING_DT_ONLY 0x1
-#define ADV_INQ_CLOCKING_ST_AND_DT 0x3
-
/*
* Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
* and CmdDt (Command Support Data) field bit definitions.
#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
-#define MS_CMD_DONE 0x00
-#define MS_EXTEND 0x01
#define MS_SDTR_LEN 0x03
-#define MS_SDTR_CODE 0x01
#define MS_WDTR_LEN 0x02
-#define MS_WDTR_CODE 0x03
-#define MS_MDP_LEN 0x05
-#define MS_MDP_CODE 0x00
-
-/*
- * Inquiry data structure and bitfield macros
- *
- * Only quantities of more than 1 bit are shifted, since the others are
- * just tested for true or false. C bitfields aren't portable between big
- * and little-endian platforms so they are not used.
- */
-
-#define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
-#define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
-#define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
-#define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
-#define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
-#define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
-#define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
-#define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
-#define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
-#define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
-#define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
-#define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
-#define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
-#define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
-#define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
-#define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
-#define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
-#define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
-#define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
-#define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
-
-typedef struct {
- uchar periph;
- uchar devtype;
- uchar ver;
- uchar byte3;
- uchar add_len;
- uchar res1;
- uchar res2;
- uchar flags;
- uchar vendor_id[8];
- uchar product_id[16];
- uchar product_rev_level[4];
-} ASC_SCSI_INQUIRY;
#define ASC_SG_LIST_PER_Q 7
#define QS_FREE 0x00
uchar sdtr_period_offset[ASC_MAX_TID + 1];
ushort pci_slot_info;
uchar adapter_info[6];
- struct device *dev;
} ASC_DVC_CFG;
#define ASC_DEF_DVC_CNTL 0xFFFF
static void AscSetBank(PortAddr, uchar);
static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
#ifdef CONFIG_ISA
-static ushort AscGetIsaDmaChannel(PortAddr);
-static ushort AscSetIsaDmaChannel(PortAddr, ushort);
-static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
static uchar AscGetIsaDmaSpeed(PortAddr);
#endif /* CONFIG_ISA */
static uchar AscReadLramByte(PortAddr, ushort);
static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
static ushort AscInitFromEEP(ASC_DVC_VAR *);
-static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
static int AscTestExternalLram(ASC_DVC_VAR *);
static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
static ushort AscGetEisaChipCfg(PortAddr);
#endif /* CONFIG_ISA */
static uchar AscGetChipScsiCtrl(PortAddr);
-static uchar AscSetChipScsiID(PortAddr, uchar);
static uchar AscGetChipVersion(PortAddr, ushort);
-static ushort AscGetChipBusType(PortAddr);
static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
-static int AscFindSignature(PortAddr);
static void AscToggleIRQAct(PortAddr);
-static uchar AscGetChipIRQ(PortAddr, ushort);
-static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
-static ushort AscGetChipBiosAddress(PortAddr, ushort);
static inline ulong DvcEnterCritical(void);
static inline void DvcLeaveCritical(ulong);
-static ushort AscGetChipBiosAddress(PortAddr, ushort);
static void DvcSleepMilliSecond(ASC_DCNT);
static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
-static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
-static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
-static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
+static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *);
static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
static int AscISR(ASC_DVC_VAR *);
static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
#ifdef CONFIG_ISA
static void AscEnableIsaDma(uchar);
#endif /* CONFIG_ISA */
-static ASC_DCNT AscGetMaxDmaCount(ushort);
static const char *advansys_info(struct Scsi_Host *shost);
/*
#define BIOS_CTRL_AIPP_DIS 0x2000
#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
-#define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
-#define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
/*
* XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
* #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
*/
#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
-#define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
-#define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
/*
* Byte I/O register address from base of 'iop_base'.
ushort serial1; /* EEPROM serial number word 1 */
ushort serial2; /* EEPROM serial number word 2 */
ushort serial3; /* EEPROM serial number word 3 */
- struct device *dev; /* pointer to the pci dev structure for this board */
} ADV_DVC_CFG;
struct adv_dvc_var;
*/
static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
static int AdvISR(ADV_DVC_VAR *);
-static int AdvInitGetConfig(ADV_DVC_VAR *);
static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
* Internal Adv Library functions.
*/
static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
-static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
(sizeof(ADV_SG_BLOCK) * \
((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
-/*
- * Inquiry data structure and bitfield macros
- *
- * Using bitfields to access the subchar data isn't portable across
- * endianness, so instead mask and shift. Only quantities of more
- * than 1 bit are shifted, since the others are just tested for true
- * or false.
- */
-
-#define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
-#define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
-#define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
-#define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
-#define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
-#define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
-#define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
-#define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
-#define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
-#define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
-#define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
-#define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
-#define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
-#define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
-#define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
-#define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
-#define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
-#define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
-#define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
-#define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
-
-typedef struct {
- uchar periph; /* peripheral device type [0:4] */
- /* peripheral qualifier [5:7] */
- uchar devtype; /* device type modifier (for SCSI I) [0:6] */
- /* RMB - removable medium bit [7] */
- uchar ver; /* ANSI approved version [0:2] */
- /* ECMA version [3:5] */
- /* ISO version [6:7] */
- uchar byte3; /* response data format [0:3] */
- /* 0 SCSI 1 */
- /* 1 CCS */
- /* 2 SCSI-2 */
- /* 3-F reserved */
- /* reserved [4:5] */
- /* terminate I/O process bit (see 5.6.22) [6] */
- /* asynch. event notification (processor) [7] */
- uchar add_len; /* additional length */
- uchar res1; /* reserved */
- uchar res2; /* reserved */
- uchar flags; /* soft reset implemented [0] */
- /* command queuing [1] */
- /* reserved [2] */
- /* linked command for this logical unit [3] */
- /* synchronous data transfer [4] */
- /* wide bus 16 bit data transfer [5] */
- /* wide bus 32 bit data transfer [6] */
- /* relative addressing mode [7] */
- uchar vendor_id[8]; /* vendor identification */
- uchar product_id[16]; /* product identification */
- uchar product_rev_level[4]; /* product revision level */
- uchar vendor_specific[20]; /* vendor specific */
- uchar info; /* information unit supported [0] */
- /* quick arbitrate supported [1] */
- /* clocking field [2:3] */
- /* reserved [4:7] */
- uchar res3; /* reserved */
-} ADV_SCSI_INQUIRY; /* 58 bytes */
-
/*
* --- Driver Constants and Macros
*/
* field. It is guaranteed to be allocated from DMA-able memory.
*/
typedef struct asc_board {
+ struct device *dev;
int id; /* Board Id */
uint flags; /* Board flags */
union {
/*
* The following fields are used only for Narrow Boards.
*/
- /* The following three structures must be in DMA-able memory. */
- ASC_SCSI_REQ_Q scsireqq;
- ASC_CAP_INFO cap_info;
- ASC_SCSI_INQUIRY inquiry;
uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
/*
* The following fields are used only for Wide Boards.
/*
* --- Driver Function Prototypes
- *
- * advansys.h contains function prototypes for functions global to Linux.
*/
static int advansys_slave_configure(struct scsi_device *);
static int asc_prt_line(char *, int, char *fmt, ...);
#endif /* CONFIG_PROC_FS */
-/* Declaration for Asc Library internal functions referenced by driver. */
-static int AscFindSignature(PortAddr);
-static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
-
/* Statistics function prototypes. */
#ifdef ADVANSYS_STATS
#ifdef CONFIG_PROC_FS
cp = boardp->prtbuf;
cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
- cnt =
- asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
+ cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
cplen);
totcnt += cnt;
leftlen -= cnt;
for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
cp = boardp->prtbuf;
cplen = asc_prt_target_stats(shost, tgt_id, cp,
- ASC_PRTBUF_SIZE);
+ ASC_PRTBUF_SIZE);
ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
- cnt =
- asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
- cplen);
+ cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
+ cplen);
totcnt += cnt;
leftlen -= cnt;
if (leftlen == 0) {
ASC_DVC_VAR *asc_dvc_varp;
ADV_DVC_VAR *adv_dvc_varp;
char *busname;
- int iolen;
char *widename = NULL;
boardp = ASC_BOARDP(shost);
} else {
busname = "ISA";
}
- /* Don't reference 'shost->n_io_port'; It may be truncated. */
sprintf(info,
"AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
ASC_VERSION, busname,
(ulong)shost->io_port,
- (ulong)shost->io_port + boardp->asc_n_io_port -
- 1, shost->irq, shost->dma_channel);
+ (ulong)shost->io_port + ASC_IOADR_GAP - 1,
+ shost->irq, shost->dma_channel);
} else {
if (asc_dvc_varp->bus_type & ASC_IS_VL) {
busname = "VL";
}
} else {
busname = "?";
- ASC_PRINT2
- ("advansys_info: board %d: unknown bus type %d\n",
- boardp->id, asc_dvc_varp->bus_type);
+ ASC_PRINT2("advansys_info: board %d: unknown "
+ "bus type %d\n", boardp->id,
+ asc_dvc_varp->bus_type);
}
- /* Don't reference 'shost->n_io_port'; It may be truncated. */
sprintf(info,
"AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
- ASC_VERSION, busname,
- (ulong)shost->io_port,
- (ulong)shost->io_port + boardp->asc_n_io_port -
- 1, shost->irq);
+ ASC_VERSION, busname, (ulong)shost->io_port,
+ (ulong)shost->io_port + ASC_IOADR_GAP - 1,
+ shost->irq);
}
} else {
/*
*/
adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
- iolen = ADV_3550_IOLEN;
widename = "Ultra-Wide";
} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
- iolen = ADV_38C0800_IOLEN;
widename = "Ultra2-Wide";
} else {
- iolen = ADV_38C1600_IOLEN;
widename = "Ultra3-Wide";
}
sprintf(info,
"AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
- (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
+ (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq);
}
ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
ASC_DBG(1, "advansys_info: end\n");
/* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
if (asc_dvc_varp->err_code) {
- ASC_PRINT2
- ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
- boardp->id, asc_dvc_varp->err_code);
+ ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
+ "error: 0x%x\n", boardp->id,
+ asc_dvc_varp->err_code);
ret = FAILED;
} else if (status) {
- ASC_PRINT2
- ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
- boardp->id, status);
+ ASC_PRINT2("advansys_reset: board %d: SCSI bus reset "
+ "warning: 0x%x\n", boardp->id, status);
} else {
- ASC_PRINT1
- ("advansys_reset: board %d: SCSI bus reset successful.\n",
- boardp->id);
+ ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
+ "successful.\n", boardp->id);
}
ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
switch (AdvResetChipAndSB(adv_dvc_varp)) {
case ASC_TRUE:
- ASC_PRINT1
- ("advansys_reset: board %d: SCSI bus reset successful.\n",
- boardp->id);
+ ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
+ "successful.\n", boardp->id);
break;
case ASC_FALSE:
default:
- ASC_PRINT1
- ("advansys_reset: board %d: SCSI bus reset error.\n",
- boardp->id);
+ ASC_PRINT1("advansys_reset: board %d: SCSI bus reset "
+ "error.\n", boardp->id);
ret = FAILED;
break;
}
* is returned in 'last_scp'.
*/
if (done_scp == NULL) {
- done_scp =
- asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
+ done_scp = asc_dequeue_list(&boardp->active, &last_scp,
+ ASC_TID_ALL);
for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
tscp->result = HOST_BYTE(DID_RESET);
}
* to DID_RESET.
*/
if (done_scp == NULL) {
- done_scp =
- asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
+ done_scp = asc_dequeue_list(&boardp->waiting, &last_scp,
+ ASC_TID_ALL);
for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
tscp->result = HOST_BYTE(DID_RESET);
}
/*
* Complete all the 'done_scp' requests.
*/
- if (done_scp != NULL) {
+ if (done_scp)
asc_scsi_done_list(done_scp);
- }
ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
return result;
}
+static void
+advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc)
+{
+ ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id;
+ ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng;
+
+ if (sdev->lun == 0) {
+ ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr;
+ if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) {
+ asc_dvc->init_sdtr |= tid_bit;
+ } else {
+ asc_dvc->init_sdtr &= ~tid_bit;
+ }
+
+ if (orig_init_sdtr != asc_dvc->init_sdtr)
+ AscAsyncFix(asc_dvc, sdev);
+ }
+
+ if (sdev->tagged_supported) {
+ if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) {
+ if (sdev->lun == 0) {
+ asc_dvc->cfg->can_tagged_qng |= tid_bit;
+ asc_dvc->use_tagged_qng |= tid_bit;
+ }
+ scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
+ asc_dvc->max_dvc_qng[sdev->id]);
+ }
+ } else {
+ if (sdev->lun == 0) {
+ asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
+ asc_dvc->use_tagged_qng &= ~tid_bit;
+ }
+ scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+ }
+
+ if ((sdev->lun == 0) &&
+ (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) {
+ AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
+ asc_dvc->cfg->disc_enable);
+ AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
+ asc_dvc->use_tagged_qng);
+ AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
+ asc_dvc->cfg->can_tagged_qng);
+
+ asc_dvc->max_dvc_qng[sdev->id] =
+ asc_dvc->cfg->max_tag_qng[sdev->id];
+ AscWriteLramByte(asc_dvc->iop_base,
+ (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id),
+ asc_dvc->max_dvc_qng[sdev->id]);
+ }
+}
+
/*
- * Set the number of commands to queue per device for the
- * specified host adapter.
+ * Wide Transfers
+ *
+ * If the EEPROM enabled WDTR for the device and the device supports wide
+ * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and
+ * write the new value to the microcode.
*/
-static int advansys_slave_configure(struct scsi_device *device)
+static void
+advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask)
{
- asc_board_t *boardp;
+ unsigned short cfg_word;
+ AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
+ if ((cfg_word & tidmask) != 0)
+ return;
+
+ cfg_word |= tidmask;
+ AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
- boardp = ASC_BOARDP(device->host);
- boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
/*
- * Save a pointer to the device and set its initial/maximum
- * queue depth. Only save the pointer for a lun0 dev though.
+ * Clear the microcode SDTR and WDTR negotiation done indicators for
+ * the target to cause it to negotiate with the new setting set above.
+ * WDTR when accepted causes the target to enter asynchronous mode, so
+ * SDTR must be negotiated.
*/
- if (device->lun == 0)
- boardp->device[device->id] = device;
- if (device->tagged_supported) {
- if (ASC_NARROW_BOARD(boardp)) {
- scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
- boardp->dvc_var.asc_dvc_var.
- max_dvc_qng[device->id]);
- } else {
- scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
- boardp->dvc_var.adv_dvc_var.
- max_dvc_qng);
+ AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+ cfg_word &= ~tidmask;
+ AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+ AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
+ cfg_word &= ~tidmask;
+ AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
+}
+
+/*
+ * Synchronous Transfers
+ *
+ * If the EEPROM enabled SDTR for the device and the device
+ * supports synchronous transfers, then turn on the device's
+ * 'sdtr_able' bit. Write the new value to the microcode.
+ */
+static void
+advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask)
+{
+ unsigned short cfg_word;
+ AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
+ if ((cfg_word & tidmask) != 0)
+ return;
+
+ cfg_word |= tidmask;
+ AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
+
+ /*
+ * Clear the microcode "SDTR negotiation" done indicator for the
+ * target to cause it to negotiate with the new setting set above.
+ */
+ AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+ cfg_word &= ~tidmask;
+ AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
+}
+
+/*
+ * PPR (Parallel Protocol Request) Capable
+ *
+ * If the device supports DT mode, then it must be PPR capable.
+ * The PPR message will be used in place of the SDTR and WDTR
+ * messages to negotiate synchronous speed and offset, transfer
+ * width, and protocol options.
+ */
+static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc,
+ AdvPortAddr iop_base, unsigned short tidmask)
+{
+ AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
+ adv_dvc->ppr_able |= tidmask;
+ AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able);
+}
+
+static void
+advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc)
+{
+ AdvPortAddr iop_base = adv_dvc->iop_base;
+ unsigned short tidmask = 1 << sdev->id;
+
+ if (sdev->lun == 0) {
+ /*
+ * Handle WDTR, SDTR, and Tag Queuing. If the feature
+ * is enabled in the EEPROM and the device supports the
+ * feature, then enable it in the microcode.
+ */
+
+ if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr)
+ advansys_wide_enable_wdtr(iop_base, tidmask);
+ if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr)
+ advansys_wide_enable_sdtr(iop_base, tidmask);
+ if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr)
+ advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask);
+
+ /*
+ * Tag Queuing is disabled for the BIOS which runs in polled
+ * mode and would see no benefit from Tag Queuing. Also by
+ * disabling Tag Queuing in the BIOS devices with Tag Queuing
+ * bugs will at least work with the BIOS.
+ */
+ if ((adv_dvc->tagqng_able & tidmask) &&
+ sdev->tagged_supported) {
+ unsigned short cfg_word;
+ AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
+ cfg_word |= tidmask;
+ AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
+ cfg_word);
+ AdvWriteByteLram(iop_base,
+ ASC_MC_NUMBER_OF_MAX_CMD + sdev->id,
+ adv_dvc->max_dvc_qng);
}
+ }
+
+ if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) {
+ scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
+ adv_dvc->max_dvc_qng);
} else {
- scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
+ scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
}
- ASC_DBG4(1,
- "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
- (ulong)device, (ulong)boardp, device->id, device->queue_depth);
+}
+
+/*
+ * Set the number of commands to queue per device for the
+ * specified host adapter.
+ */
+static int advansys_slave_configure(struct scsi_device *sdev)
+{
+ asc_board_t *boardp = ASC_BOARDP(sdev->host);
+ boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
+
+ /*
+ * Save a pointer to the sdev and set its initial/maximum
+ * queue depth. Only save the pointer for a lun0 dev though.
+ */
+ if (sdev->lun == 0)
+ boardp->device[sdev->id] = sdev;
+
+ if (ASC_NARROW_BOARD(boardp))
+ advansys_narrow_slave_configure(sdev,
+ &boardp->dvc_var.asc_dvc_var);
+ else
+ advansys_wide_slave_configure(sdev,
+ &boardp->dvc_var.adv_dvc_var);
+
return 0;
}
ASC_DBG(2, "asc_scsi_done_list: begin\n");
while (scp != NULL) {
asc_board_t *boardp;
- struct device *dev;
ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
tscp = REQPNEXT(scp);
boardp = ASC_BOARDP(scp->device->host);
- if (ASC_NARROW_BOARD(boardp))
- dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
- else
- dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
-
if (scp->use_sg)
- dma_unmap_sg(dev,
+ 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(dev, scp->SCp.dma_handle,
+ dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
scp->request_bufflen,
scp->sc_data_direction);
case ASC_NOERROR:
ASC_STATS(scp->device->host, exe_noerror);
/*
- * Increment monotonically increasing per device successful
- * request counter. Wrapping doesn't matter.
+ * Increment monotonically increasing per device
+ * successful request counter. Wrapping doesn't matter.
*/
boardp->reqcnt[scp->device->id]++;
asc_enqueue(&boardp->active, scp, ASC_BACK);
- ASC_DBG(1,
- "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
+ ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), "
+ "ASC_NOERROR\n");
break;
case ASC_BUSY:
/*
- * Caller will enqueue request on the target's waiting queue
- * and retry later.
+ * Caller will enqueue request on the target's waiting
+ * queue and retry later.
*/
ASC_STATS(scp->device->host, exe_busy);
break;
case ASC_ERROR:
- ASC_PRINT2
- ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
- boardp->id, asc_dvc_varp->err_code);
+ ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+ "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
+ boardp->id, asc_dvc_varp->err_code);
ASC_STATS(scp->device->host, exe_error);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
break;
default:
- ASC_PRINT2
- ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
- boardp->id, asc_dvc_varp->err_code);
+ ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+ "AscExeScsiQueue() unknown, err_code 0x%x\n",
+ boardp->id, asc_dvc_varp->err_code);
ASC_STATS(scp->device->host, exe_unknown);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
*/
switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
case ASC_NOERROR:
- ASC_DBG(3,
- "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
+ ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req "
+ "ASC_NOERROR\n");
break;
case ASC_BUSY:
- ASC_DBG(1,
- "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
+ ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
+ "ASC_BUSY\n");
/*
- * If busy is returned the request has not been enqueued.
- * It will be enqueued by the caller on the target's waiting
- * queue and retried later.
+ * If busy is returned the request has not been
+ * enqueued. It will be enqueued by the caller on the
+ * target's waiting queue and retried later.
*
- * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
- * count wide board busy conditions. They are updated in
- * adv_build_req and adv_get_sglist, respectively.
+ * The asc_stats fields 'adv_build_noreq' and
+ * 'adv_build_nosg' count wide board busy conditions.
+ * They are updated in adv_build_req and
+ * adv_get_sglist, respectively.
*/
return ASC_BUSY;
case ASC_ERROR:
* by the caller.
*/
default:
- ASC_DBG(1,
- "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
+ ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
+ "ASC_ERROR\n");
ASC_STATS(scp->device->host, build_error);
return ASC_ERROR;
}
case ASC_NOERROR:
ASC_STATS(scp->device->host, exe_noerror);
/*
- * Increment monotonically increasing per device successful
- * request counter. Wrapping doesn't matter.
+ * Increment monotonically increasing per device
+ * successful request counter. Wrapping doesn't matter.
*/
boardp->reqcnt[scp->device->id]++;
asc_enqueue(&boardp->active, scp, ASC_BACK);
- ASC_DBG(1,
- "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
+ ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), "
+ "ASC_NOERROR\n");
break;
case ASC_BUSY:
/*
- * Caller will enqueue request on the target's waiting queue
- * and retry later.
+ * Caller will enqueue request on the target's waiting
+ * queue and retry later.
*/
ASC_STATS(scp->device->host, exe_busy);
break;
case ASC_ERROR:
- ASC_PRINT2
- ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
- boardp->id, adv_dvc_varp->err_code);
+ ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+ "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
+ boardp->id, adv_dvc_varp->err_code);
ASC_STATS(scp->device->host, exe_error);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
break;
default:
- ASC_PRINT2
- ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
- boardp->id, adv_dvc_varp->err_code);
+ ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
+ "AdvExeScsiQueue() unknown, err_code 0x%x\n",
+ boardp->id, adv_dvc_varp->err_code);
ASC_STATS(scp->device->host, exe_unknown);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
*/
static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
{
- struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
-
/*
* Mutually exclusive access is required to 'asc_scsi_q' and
* 'asc_sg_head' until after the request is started.
* is supported.
*/
if (scp->cmd_len > ASC_MAX_CDB_LEN) {
- ASC_PRINT3
- ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
- boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
+ ASC_PRINT3("asc_build_req: board %d: cmd_len %d > "
+ "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
+ ASC_MAX_CDB_LEN);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
return ASC_ERROR;
*/
ASC_STATS(scp->device->host, cont_cnt);
scp->SCp.dma_handle = scp->request_bufflen ?
- dma_map_single(dev, scp->request_buffer,
+ 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);
struct scatterlist *slp;
slp = (struct scatterlist *)scp->request_buffer;
- use_sg =
- dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+ 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(dev, slp, scp->use_sg,
+ 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);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
ADV_SCSI_REQ_Q *scsiqp;
int i;
int ret;
- struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
/*
* Allocate an adv_req_t structure from the board to execute
if (scp->request_bufflen) {
scsiqp->vdata_addr = scp->request_buffer;
scp->SCp.dma_handle =
- dma_map_single(dev, scp->request_buffer,
+ dma_map_single(boardp->dev, scp->request_buffer,
scp->request_bufflen,
scp->sc_data_direction);
} else {
int use_sg;
slp = (struct scatterlist *)scp->request_buffer;
- use_sg =
- dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+ 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,
- scp->device->host->sg_tablesize);
- dma_unmap_sg(dev, slp, scp->use_sg,
+ ASC_PRINT3("adv_build_req: board %d: use_sg %d > "
+ "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg,
+ scp->device->host->sg_tablesize);
+ dma_unmap_sg(boardp->dev, slp, scp->use_sg,
scp->sc_data_direction);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
/*
- * Free the 'adv_req_t' structure by adding it back to the
- * board free list.
+ * Free the 'adv_req_t' structure by adding it back
+ * to the board free list.
*/
reqp->next_reqp = boardp->adv_reqp;
boardp->adv_reqp = reqp;
return ASC_ERROR;
}
- if ((ret =
- adv_get_sglist(boardp, reqp, scp,
- use_sg)) != ADV_SUCCESS) {
+ ret = adv_get_sglist(boardp, reqp, scp, use_sg);
+ if (ret != ADV_SUCCESS) {
/*
- * Free the adv_req_t structure by adding it back to the
- * board free list.
+ * Free the adv_req_t structure by adding it back to
+ * the board free list.
*/
reqp->next_reqp = boardp->adv_reqp;
boardp->adv_reqp = reqp;
ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
scp->result = 0;
- /*
- * If an INQUIRY command completed successfully, then call
- * the AscInquiryHandling() function to set-up the device.
- */
- if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
- (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
- AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
- (ASC_SCSI_INQUIRY *)scp->
- request_buffer);
- }
-
/*
* Check for an underrun condition.
*
* If there was no error and an underrun condition, then
- * then return the number of underrun bytes.
+ * return the number of underrun bytes.
*/
if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
qdonep->remain_bytes <= scp->request_bufflen) {
boardp->asc_n_io_port);
ASC_PRT_NEXT();
- /* 'shost->n_io_port' may be truncated because it is only one byte. */
- len = asc_prt_line(cp, leftlen,
- " io_port 0x%x, n_io_port 0x%x\n",
- shost->io_port, shost->n_io_port);
+ len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port);
ASC_PRT_NEXT();
if (ASC_NARROW_BOARD(boardp)) {
* Return the BIOS address of the adapter at the specified
* I/O port and with the specified bus type.
*/
-static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
+static unsigned short __devinit
+AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type)
{
- ushort cfg_lsw;
- ushort bios_addr;
+ unsigned short cfg_lsw;
+ unsigned short bios_addr;
/*
* The PCI BIOS is re-located by the motherboard BIOS. Because
* of this the driver can not determine where a PCI BIOS is
* loaded and executes.
*/
- if (bus_type & ASC_IS_PCI) {
- return (0);
- }
+ if (bus_type & ASC_IS_PCI)
+ return 0;
+
#ifdef CONFIG_ISA
if ((bus_type & ASC_IS_EISA) != 0) {
cfg_lsw = AscGetEisaChipCfg(iop_base);
cfg_lsw &= 0x000F;
- bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
- (cfg_lsw * ASC_BIOS_BANK_SIZE));
- return (bios_addr);
- } /* if */
+ bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE;
+ return bios_addr;
+ }
#endif /* CONFIG_ISA */
cfg_lsw = AscGetChipCfgLsw(iop_base);
/*
* ISA PnP uses the top bit as the 32K BIOS flag
*/
- if (bus_type == ASC_IS_ISAPNP) {
+ if (bus_type == ASC_IS_ISAPNP)
cfg_lsw &= 0x7FFF;
- }
- /* if */
- bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
- ASC_BIOS_MIN_ADDR);
- return (bios_addr);
+ bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE;
+ return bios_addr;
}
/*
printk(" host_busy %u, host_no %d, last_reset %d,\n",
s->host_busy, s->host_no, (unsigned)s->last_reset);
- printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
- (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
+ printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n",
+ (ulong)s->base, (ulong)s->io_port, s->irq);
printk(" dma_channel %d, this_id %d, can_queue %d,\n",
s->dma_channel, s->this_id, s->can_queue);
printk(" timeout_per_command %d\n", s->timeout_per_command);
- printk
- (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
- (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
- s->result);
+ printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n",
+ s->scsi_done, s->done, s->host_scribble, s->result);
printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
}
{
printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
- printk
- (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
- h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
+ printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl "
+ "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
- printk
- (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
- h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
- (unsigned)h->init_sdtr);
+ printk(" bus_type %d, isr_callback 0x%p, exe_callback 0x%p, "
+ "init_sdtr 0x%x,\n", h->bus_type, h->isr_callback,
+ h->exe_callback, (unsigned)h->init_sdtr);
- printk
- (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
- (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
- (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
+ printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, "
+ "chip_no 0x%x,\n", (unsigned)h->sdtr_done,
+ (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready,
+ (unsigned)h->chip_no);
- printk
- (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
- (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
- (unsigned)h->scsi_reset_wait);
+ printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait "
+ "%u,\n", (unsigned)h->queue_full_or_busy,
+ (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait);
- printk
- (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
- (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
- (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
+ printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, "
+ "in_critical_cnt %u,\n", (unsigned)h->is_in_int,
+ (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng,
+ (unsigned)h->in_critical_cnt);
- printk
- (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
- (unsigned)h->last_q_shortage, (unsigned)h->init_state,
- (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
+ printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, "
+ "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage,
+ (unsigned)h->init_state, (unsigned)h->no_scam,
+ (unsigned)h->pci_fix_asyn_xfer);
printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
}
return (AscGetChipScsiID(iop_base));
}
-static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base)
+static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base)
{
- uchar sc;
+ unsigned char sc;
AscSetBank(iop_base, 1);
sc = inp(iop_base + IOP_REG_SC);
AscSetBank(iop_base, 0);
- return (sc);
+ return sc;
}
-static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type)
+static unsigned char __devinit
+AscGetChipVersion(PortAddr iop_base, unsigned short bus_type)
{
- if ((bus_type & ASC_IS_EISA) != 0) {
+ if (bus_type & ASC_IS_EISA) {
PortAddr eisa_iop;
- uchar revision;
+ unsigned char revision;
eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
(PortAddr) ASC_EISA_REV_IOP_MASK;
revision = inp(eisa_iop);
- return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
+ return ASC_CHIP_MIN_VER_EISA - 1 + revision;
}
- return (AscGetChipVerNo(iop_base));
-}
-
-static ushort __devinit AscGetChipBusType(PortAddr iop_base)
-{
- ushort chip_ver;
-
- chip_ver = AscGetChipVerNo(iop_base);
- if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
- && (chip_ver <= ASC_CHIP_MAX_VER_VL)
- ) {
- if (((iop_base & 0x0C30) == 0x0C30)
- || ((iop_base & 0x0C50) == 0x0C50)
- ) {
- return (ASC_IS_EISA);
- }
- return (ASC_IS_VL);
- }
- if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
- (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
- if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
- return (ASC_IS_ISAPNP);
- }
- return (ASC_IS_ISA);
- } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
- (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
- return (ASC_IS_PCI);
- }
- return (0);
+ return AscGetChipVerNo(iop_base);
}
static ASC_DCNT
(uchar *)&ext_msg,
sizeof(EXT_MSG) >> 1);
- if (ext_msg.msg_type == MS_EXTEND &&
- ext_msg.msg_req == MS_SDTR_CODE &&
+ if (ext_msg.msg_type == EXTENDED_MESSAGE &&
+ ext_msg.msg_req == EXTENDED_SDTR &&
ext_msg.msg_len == MS_SDTR_LEN) {
sdtr_accept = TRUE;
if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
q_cntl);
AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
return (0);
- } else if (ext_msg.msg_type == MS_EXTEND &&
- ext_msg.msg_req == MS_WDTR_CODE &&
+ } else if (ext_msg.msg_type == EXTENDED_MESSAGE &&
+ ext_msg.msg_req == EXTENDED_WDTR &&
ext_msg.msg_len == MS_WDTR_LEN) {
ext_msg.wdtr_width = 0;
(uchar *)&out_msg,
sizeof(EXT_MSG) >> 1);
- if ((out_msg.msg_type == MS_EXTEND) &&
+ if ((out_msg.msg_type == EXTENDED_MESSAGE) &&
(out_msg.msg_len == MS_SDTR_LEN) &&
- (out_msg.msg_req == MS_SDTR_CODE)) {
+ (out_msg.msg_req == EXTENDED_SDTR)) {
asc_dvc->init_sdtr &= ~target_id;
asc_dvc->sdtr_done &= ~target_id;
PortAddr iop_base;
iop_base = asc_dvc->iop_base;
- sdtr_buf.msg_type = MS_EXTEND;
+ sdtr_buf.msg_type = EXTENDED_MESSAGE;
sdtr_buf.msg_len = MS_SDTR_LEN;
- sdtr_buf.msg_req = MS_SDTR_CODE;
+ sdtr_buf.msg_req = EXTENDED_SDTR;
sdtr_buf.xfer_period = sdtr_period;
sdtr_offset &= ASC_SYN_MAX_OFFSET;
sdtr_buf.req_ack_offset = sdtr_offset;
warn_code |= AscInitAscDvcVar(asc_dvc);
warn_code |= AscInitFromEEP(asc_dvc);
asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
- if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
+ if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
- }
} else {
asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
}
- return (warn_code);
+ return warn_code;
}
-static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
+static unsigned short __devinit
+AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc)
{
- ushort warn_code = 0;
+ PortAddr iop_base = asc_dvc->iop_base;
+ unsigned short cfg_msw;
+ unsigned short warn_code = 0;
asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
if (asc_dvc->err_code != 0)
- return (UW_ERR);
- if (AscFindSignature(asc_dvc->iop_base)) {
- warn_code |= AscInitFromAscDvcVar(asc_dvc);
- asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
- } else {
+ return UW_ERR;
+ if (!AscFindSignature(asc_dvc->iop_base)) {
asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
+ return 0;
}
- return (warn_code);
-}
-
-static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
-{
- PortAddr iop_base;
- ushort cfg_msw;
- ushort warn_code;
- iop_base = asc_dvc->iop_base;
- warn_code = 0;
cfg_msw = AscGetChipCfgMsw(iop_base);
if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
}
#ifdef CONFIG_PCI
if (asc_dvc->bus_type & ASC_IS_PCI) {
- struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev);
cfg_msw &= 0xFFC0;
AscSetChipCfgMsw(iop_base, cfg_msw);
if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
}
#endif /* CONFIG_ISA */
- return (warn_code);
+
+ asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
+ return warn_code;
}
static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
}
asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
- if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
- AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
- asc_dvc->bus_type = ASC_IS_ISAPNP;
- }
#ifdef CONFIG_ISA
if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
+ if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) {
+ AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
+ asc_dvc->bus_type = ASC_IS_ISAPNP;
+ }
asc_dvc->cfg->isa_dma_channel =
(uchar)AscGetIsaDmaChannel(iop_base);
}
return (n_error);
}
-static void
-AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
+static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev)
{
- uchar dvc_type;
- ASC_SCSI_BIT_ID_TYPE tid_bits;
-
- dvc_type = ASC_INQ_DVC_TYPE(inq);
- tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
+ char type = sdev->type;
+ ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id;
if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
if (!(asc_dvc->init_sdtr & tid_bits)) {
- if ((dvc_type == TYPE_ROM) &&
- (strncmp(inq->vendor_id, "HP ", 3) == 0)) {
+ if ((type == TYPE_ROM) &&
+ (strncmp(sdev->vendor, "HP ", 3) == 0)) {
asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
}
asc_dvc->pci_fix_asyn_xfer |= tid_bits;
- if ((dvc_type == TYPE_PROCESSOR) ||
- (dvc_type == TYPE_SCANNER) ||
- (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
+ if ((type == TYPE_PROCESSOR) ||
+ (type == TYPE_SCANNER) || (type == TYPE_ROM) ||
+ (type == TYPE_TAPE)) {
asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
}
if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
AscSetRunChipSynRegAtID(asc_dvc->iop_base,
- tid_no,
- ASYN_SDTR_DATA_FIX_PCI_REV_AB);
- }
- }
- }
- return;
-}
-
-static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
-{
- if ((inq->add_len >= 32) &&
- (strncmp(inq->vendor_id, "QUANTUM XP34301", 15) == 0) &&
- (strncmp(inq->product_rev_level, "1071", 4) == 0)) {
- return 0;
- }
- return 1;
-}
-
-static void
-AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
-{
- ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
- ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
-
- orig_init_sdtr = asc_dvc->init_sdtr;
- orig_use_tagged_qng = asc_dvc->use_tagged_qng;
-
- asc_dvc->init_sdtr &= ~tid_bit;
- asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
- asc_dvc->use_tagged_qng &= ~tid_bit;
-
- if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
- if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
- asc_dvc->init_sdtr |= tid_bit;
- }
- if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
- ASC_INQ_CMD_QUEUE(inq)) {
- if (AscTagQueuingSafe(inq)) {
- asc_dvc->use_tagged_qng |= tid_bit;
- asc_dvc->cfg->can_tagged_qng |= tid_bit;
+ sdev->id,
+ ASYN_SDTR_DATA_FIX_PCI_REV_AB);
}
}
}
- if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
- AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
- asc_dvc->cfg->disc_enable);
- AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
- asc_dvc->use_tagged_qng);
- AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
- asc_dvc->cfg->can_tagged_qng);
-
- asc_dvc->max_dvc_qng[tid_no] =
- asc_dvc->cfg->max_tag_qng[tid_no];
- AscWriteLramByte(asc_dvc->iop_base,
- (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
- asc_dvc->max_dvc_qng[tid_no]);
- }
- if (orig_init_sdtr != asc_dvc->init_sdtr) {
- AscAsyncFix(asc_dvc, tid_no, inq);
- }
- return;
}
static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
* For a non-fatal error return a warning code. If there are no warnings
* then 0 is returned.
*/
-static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
+static int __devinit
+AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc)
{
unsigned short warn_code = 0;
AdvPortAddr iop_base = asc_dvc->iop_base;
- struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev);
u16 cmd;
int status;
/*
* Microcode operating variables for WDTR, SDTR, and command tag
- * queuing will be set in AdvInquiryHandling() based on what a
+ * queuing will be set in slave_configure() based on what a
* device reports it is capable of in Inquiry byte 7.
*
* If SCSI Bus Resets have been disabled, then directly set
/*
* Microcode operating variables for WDTR, SDTR, and command tag
- * queuing will be set in AdvInquiryHandling() based on what a
+ * queuing will be set in slave_configure() based on what a
* device reports it is capable of in Inquiry byte 7.
*
* If SCSI Bus Resets have been disabled, then directly set
/*
* Microcode operating variables for WDTR, SDTR, and command tag
- * queuing will be set in AdvInquiryHandling() based on what a
+ * queuing will be set in slave_configure() based on what a
* device reports it is capable of in Inquiry byte 7.
*
* If SCSI Bus Resets have been disabled, then directly set
*/
scsiq->cntl = 0;
- /*
- * If the command that completed was a SCSI INQUIRY and
- * LUN 0 was sent the command, then process the INQUIRY
- * command information for the device.
- *
- * Note: If data returned were either VPD or CmdDt data,
- * don't process the INQUIRY command information for
- * the device, otherwise may erroneously set *_able bits.
- */
- if (scsiq->done_status == QD_NO_ERROR &&
- scsiq->cdb[0] == INQUIRY &&
- scsiq->target_lun == 0 &&
- (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
- == ADV_INQ_RTN_STD_INQUIRY_DATA) {
- AdvInquiryHandling(asc_dvc, scsiq);
- }
-
/*
* Notify the driver of the completed request by passing
* the ADV_SCSI_REQ_Q pointer to its callback function.
return ADV_ERROR;
}
-/*
- * Inquiry Information Byte 7 Handling
- *
- * Handle SCSI Inquiry Command information for a device by setting
- * microcode operating variables that affect WDTR, SDTR, and Tag
- * Queuing.
- */
-static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
-{
- AdvPortAddr iop_base;
- uchar tid;
- ADV_SCSI_INQUIRY *inq;
- ushort tidmask;
- ushort cfg_word;
-
- /*
- * AdvInquiryHandling() requires up to INQUIRY information Byte 7
- * to be available.
- *
- * If less than 8 bytes of INQUIRY information were requested or less
- * than 8 bytes were transferred, then return. cdb[4] is the request
- * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
- * microcode to the transfer residual count.
- */
-
- if (scsiq->cdb[4] < 8 ||
- (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
- return;
- }
-
- iop_base = asc_dvc->iop_base;
- tid = scsiq->target_id;
-
- inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
-
- /*
- * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
- */
- if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
- return;
- } else {
- /*
- * INQUIRY Byte 7 Handling
- *
- * Use a device's INQUIRY byte 7 to determine whether it
- * supports WDTR, SDTR, and Tag Queuing. If the feature
- * is enabled in the EEPROM and the device supports the
- * feature, then enable it in the microcode.
- */
-
- tidmask = ADV_TID_TO_TIDMASK(tid);
-
- /*
- * Wide Transfers
- *
- * If the EEPROM enabled WDTR for the device and the device
- * supports wide bus (16 bit) transfers, then turn on the
- * device's 'wdtr_able' bit and write the new value to the
- * microcode.
- */
- if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
- AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
- if ((cfg_word & tidmask) == 0) {
- cfg_word |= tidmask;
- AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
- cfg_word);
-
- /*
- * Clear the microcode "SDTR negotiation" and "WDTR
- * negotiation" done indicators for the target to cause
- * it to negotiate with the new setting set above.
- * WDTR when accepted causes the target to enter
- * asynchronous mode, so SDTR must be negotiated.
- */
- AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
- cfg_word);
- cfg_word &= ~tidmask;
- AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
- cfg_word);
- AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
- cfg_word);
- cfg_word &= ~tidmask;
- AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
- cfg_word);
- }
- }
-
- /*
- * Synchronous Transfers
- *
- * If the EEPROM enabled SDTR for the device and the device
- * supports synchronous transfers, then turn on the device's
- * 'sdtr_able' bit. Write the new value to the microcode.
- */
- if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
- AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
- if ((cfg_word & tidmask) == 0) {
- cfg_word |= tidmask;
- AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
- cfg_word);
-
- /*
- * Clear the microcode "SDTR negotiation" done indicator
- * for the target to cause it to negotiate with the new
- * setting set above.
- */
- AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
- cfg_word);
- cfg_word &= ~tidmask;
- AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
- cfg_word);
- }
- }
- /*
- * If the Inquiry data included enough space for the SPI-3
- * Clocking field, then check if DT mode is supported.
- */
- if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
- (scsiq->cdb[4] >= 57 ||
- (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
- /*
- * PPR (Parallel Protocol Request) Capable
- *
- * If the device supports DT mode, then it must be PPR capable.
- * The PPR message will be used in place of the SDTR and WDTR
- * messages to negotiate synchronous speed and offset, transfer
- * width, and protocol options.
- */
- if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
- AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
- asc_dvc->ppr_able);
- asc_dvc->ppr_able |= tidmask;
- AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
- asc_dvc->ppr_able);
- }
- }
-
- /*
- * If the EEPROM enabled Tag Queuing for the device and the
- * device supports Tag Queueing, then turn on the device's
- * 'tagqng_enable' bit in the microcode and set the microcode
- * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
- * value.
- *
- * Tag Queuing is disabled for the BIOS which runs in polled
- * mode and would see no benefit from Tag Queuing. Also by
- * disabling Tag Queuing in the BIOS devices with Tag Queuing
- * bugs will at least work with the BIOS.
- */
- if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
- AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
- cfg_word |= tidmask;
- AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
- cfg_word);
-
- AdvWriteByteLram(iop_base,
- ASC_MC_NUMBER_OF_MAX_CMD + tid,
- asc_dvc->max_dvc_qng);
- }
- }
-}
-
static int __devinit
advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
{
ASC_DVC_VAR *asc_dvc_varp = NULL;
ADV_DVC_VAR *adv_dvc_varp = NULL;
int share_irq;
- int iolen = 0;
- ADV_PADDR pci_memory_address;
int warn_code, err_code;
int ret;
/*
- * Adapter found.
- *
* Register the adapter, get its configuration, and
* initialize it.
*/
ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
-
if (!shost)
return NULL;
boardp = ASC_BOARDP(shost);
memset(boardp, 0, sizeof(asc_board_t));
boardp->id = asc_board_count++;
-
- /* Initialize spinlock. */
spin_lock_init(&boardp->lock);
+ boardp->dev = dev;
/*
* Handle both narrow and wide boards.
asc_dvc_varp->iop_base = iop;
asc_dvc_varp->isr_callback = asc_isr_callback;
} else {
+#ifdef CONFIG_PCI
ASC_DBG(1, "advansys_board_found: wide board\n");
adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
adv_dvc_varp->drv_ptr = boardp;
adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
adv_dvc_varp->isr_callback = adv_isr_callback;
adv_dvc_varp->async_callback = adv_async_callback;
-#ifdef CONFIG_PCI
if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
ASC_DBG(1, "advansys_board_found: ASC-3550\n");
adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
}
-#endif /* CONFIG_PCI */
- /*
- * Map the board's registers into virtual memory for
- * PCI slave access. Only memory accesses are used to
- * access the board's registers.
- *
- * Note: The PCI register base address is not always
- * page aligned, but the address passed to ioremap()
- * must be page aligned. It is guaranteed that the
- * PCI register base address will not cross a page
- * boundary.
- */
- if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
- iolen = ADV_3550_IOLEN;
- } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
- iolen = ADV_38C0800_IOLEN;
- } else {
- iolen = ADV_38C1600_IOLEN;
- }
-#ifdef CONFIG_PCI
- pci_memory_address = pci_resource_start(pdev, 1);
- ASC_DBG1(1,
- "advansys_board_found: pci_memory_address: 0x%lx\n",
- (ulong)pci_memory_address);
- if ((boardp->ioremap_addr =
- ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
+ boardp->asc_n_io_port = pci_resource_len(pdev, 1);
+ 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_memory_address, iolen);
+ boardp->id, pci_resource_start(pdev, 1),
+ boardp->asc_n_io_port);
goto err_shost;
}
- ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n",
- (ulong)boardp->ioremap_addr);
- adv_dvc_varp->iop_base = (AdvPortAddr)
- (boardp->ioremap_addr +
- (pci_memory_address - (pci_memory_address & PAGE_MASK)));
+ adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr
ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
adv_dvc_varp->iop_base);
-#endif /* CONFIG_PCI */
/*
* Even though it isn't used to access wide boards, other
*/
boardp->ioport = iop;
- ASC_DBG2(1,
- "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
- (ushort)inp(iop + 1), (ushort)inpw(iop));
+ ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, "
+ "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1),
+ (ushort)inpw(iop));
+#endif /* CONFIG_PCI */
}
#ifdef CONFIG_PROC_FS
#endif /* CONFIG_PROC_FS */
if (ASC_NARROW_BOARD(boardp)) {
- asc_dvc_varp->cfg->dev = dev;
/*
* Set the board bus type and PCI IRQ before
* calling AscInitGetConfig().
break;
}
} else {
- adv_dvc_varp->cfg->dev = dev;
/*
* For Wide boards set PCI information before calling
* AdvInitGetConfig().
}
} else {
ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
- if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
+
+ ret = AdvInitGetConfig(pdev, adv_dvc_varp);
+ if (ret != 0) {
ASC_PRINT2
("AdvInitGetConfig: board %d: warning: 0x%x\n",
boardp->id, ret);
* Modify board configuration.
*/
ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
- switch (ret = AscInitSetConfig(asc_dvc_varp)) {
+ switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) {
case 0: /* No error. */
break;
case ASC_WARN_IO_PORT_ROTATE:
*/
boardp->init_tidmask |=
ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
-
- /*
- * Finish initializing the 'Scsi_Host' structure.
- */
- shost->irq = adv_dvc_varp->irq_no;
}
/*
* PCI Memory Mapped I/O.
*/
shost->io_port = iop;
- boardp->asc_n_io_port = iolen;
shost->this_id = adv_dvc_varp->chip_scsi_id;
shost->can_queue = adv_dvc_varp->max_host_qng;
}
- /*
- * 'n_io_port' currently is one byte.
- *
- * Set a value to 'n_io_port', but never referenced it because
- * it may be truncated.
- */
- shost->n_io_port = boardp->asc_n_io_port <= 255 ?
- boardp->asc_n_io_port : 255;
-
/*
* Following v1.3.89, 'cmd_per_lun' is no longer needed
* and should be set to zero.