From 665cc59e75674a6c82f600c850e5541fff7d526d Mon Sep 17 00:00:00 2001 From: briggs Date: Wed, 29 Aug 2001 17:25:03 +0000 Subject: [PATCH] Ensure that data accessed by the ADW driver in memory is in little-endian byte-order. This should work out to be a no-op for LE systems, and allows BE systems to use the board. Tested on PPC, reviewed by Dante. NOTE: The board/microcode does have a BIG_ENDIAN mode of operation, but it's not well-documented. That might be interesting to investigate at some point in the future, though. --- sys/dev/ic/adw.c | 26 +++++++++++++------------- sys/dev/ic/adwlib.c | 24 ++++++++++++------------ sys/dev/ic/adwmcode.h | 10 +++++----- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/sys/dev/ic/adw.c b/sys/dev/ic/adw.c index 59285881b072..b844d1438a05 100644 --- a/sys/dev/ic/adw.c +++ b/sys/dev/ic/adw.c @@ -1,4 +1,4 @@ -/* $NetBSD: adw.c,v 1.34 2001/07/31 23:12:01 dante Exp $ */ +/* $NetBSD: adw.c,v 1.35 2001/08/29 17:25:03 briggs Exp $ */ /* * Generic driver for the Advanced Systems Inc. SCSI controllers @@ -278,8 +278,8 @@ adw_init_ccb(ADW_SOFTC *sc, ADW_CCB *ccb) * put in the phystokv hash table * Never gets taken out. */ - ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr + - ADW_CCB_OFF(ccb); + ccb->hashkey = htole32(sc->sc_dmamap_control->dm_segs[0].ds_addr + + ADW_CCB_OFF(ccb)); hashnum = CCB_HASH(ccb->hashkey); ccb->nexthash = sc->sc_ccbhash[hashnum]; sc->sc_ccbhash[hashnum] = ccb; @@ -663,8 +663,8 @@ adw_build_req(ADW_SOFTC *sc, ADW_CCB *ccb) scsiqp->target_lun = periph->periph_lun; scsiqp->vsense_addr = &ccb->scsi_sense; - scsiqp->sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr + - ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense); + scsiqp->sense_addr = htole32(sc->sc_dmamap_control->dm_segs[0].ds_addr + + ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense)); scsiqp->sense_len = sizeof(struct scsipi_sense_data); /* @@ -720,9 +720,9 @@ out_bad: /* * Build scatter-gather list. */ - scsiqp->data_cnt = xs->datalen; + scsiqp->data_cnt = htole32(xs->datalen); scsiqp->vdata_addr = xs->data; - scsiqp->data_addr = ccb->dmamap_xfer->dm_segs[0].ds_addr; + scsiqp->data_addr = htole32(ccb->dmamap_xfer->dm_segs[0].ds_addr); memset(ccb->sg_block, 0, sizeof(ADW_SG_BLOCK) * ADW_NUM_SG_BLOCK); adw_build_sglist(ccb, scsiqp, ccb->sg_block); @@ -753,9 +753,9 @@ adw_build_sglist(ADW_CCB *ccb, ADW_SCSI_REQ_Q *scsiqp, ADW_SG_BLOCK *sg_block) sg_block_next_addr = (u_long) sg_block; /* allow math operation */ - sg_block_physical_addr = ccb->hashkey + + sg_block_physical_addr = le32toh(ccb->hashkey) + offsetof(struct adw_ccb, sg_block[0]); - scsiqp->sg_real_addr = sg_block_physical_addr; + scsiqp->sg_real_addr = htole32(sg_block_physical_addr); /* * If there are more than NO_OF_SG_PER_BLOCK dma segments (hw sg-list) @@ -764,8 +764,8 @@ adw_build_sglist(ADW_CCB *ccb, ADW_SCSI_REQ_Q *scsiqp, ADW_SG_BLOCK *sg_block) do { for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { - sg_block->sg_list[i].sg_addr = sg_list->ds_addr; - sg_block->sg_list[i].sg_count = sg_list->ds_len; + sg_block->sg_list[i].sg_addr = htole32(sg_list->ds_addr); + sg_block->sg_list[i].sg_count = htole32(sg_list->ds_len); if (--sg_elem_cnt == 0) { /* last entry, get out */ @@ -779,7 +779,7 @@ adw_build_sglist(ADW_CCB *ccb, ADW_SCSI_REQ_Q *scsiqp, ADW_SG_BLOCK *sg_block) sg_block_physical_addr += sizeof(ADW_SG_BLOCK); sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; - sg_block->sg_ptr = sg_block_physical_addr; + sg_block->sg_ptr = htole32(sg_block_physical_addr); sg_block = (ADW_SG_BLOCK *) sg_block_next_addr; /* virt. addr */ } while (1); } @@ -1079,7 +1079,7 @@ adw_isr_callback(ADW_SOFTC *sc, ADW_SCSI_REQ_Q *scsiq) adw_print_info(sc, scsiq->target_id); } xs->error = XS_NOERROR; - xs->resid = scsiq->data_cnt; + xs->resid = le32toh(scsiq->data_cnt); sc->sc_freeze_dev[scsiq->target_id] = 0; break; diff --git a/sys/dev/ic/adwlib.c b/sys/dev/ic/adwlib.c index 30ec05e5e684..a2390b910749 100644 --- a/sys/dev/ic/adwlib.c +++ b/sys/dev/ic/adwlib.c @@ -1,4 +1,4 @@ -/* $NetBSD: adwlib.c,v 1.21 2001/04/30 03:43:09 lukem Exp $ */ +/* $NetBSD: adwlib.c,v 1.22 2001/08/29 17:25:03 briggs Exp $ */ /* * Low level routines for the Advanced Systems Inc. SCSI controllers chips @@ -853,12 +853,12 @@ ADW_SOFTC *sc; /* * The first command issued will be placed in the stopper carrier. */ - sc->icq_sp->next_ba = ASC_CQ_STOPPER; + sc->icq_sp->next_ba = htole32(ASC_CQ_STOPPER); /* * Set RISC ICQ physical address start value. */ - ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_ICQ, sc->icq_sp->carr_ba); + ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_ICQ, le32toh(sc->icq_sp->carr_ba)); /* * Initialize the COMMA register to the same value otherwise @@ -866,7 +866,7 @@ ADW_SOFTC *sc; */ if(sc->chip_type == ADW_CHIP_ASC38C1600) { ADW_WRITE_DWORD_REGISTER(iot, ioh, IOPDW_COMMA, - sc->icq_sp->carr_ba); + le32toh(sc->icq_sp->carr_ba)); } /* @@ -885,12 +885,12 @@ ADW_SOFTC *sc; * Note: Set 'next_ba' to ASC_CQ_STOPPER. When the request is * completed the RISC will set the ASC_RQ_DONE bit. */ - sc->irq_sp->next_ba = ASC_CQ_STOPPER; + sc->irq_sp->next_ba = htole32(ASC_CQ_STOPPER); /* * Set RISC IRQ physical address start value. */ - ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_IRQ, sc->irq_sp->carr_ba); + ADW_WRITE_DWORD_LRAM(iot, ioh, ADW_MC_IRQ, le32toh(sc->irq_sp->carr_ba)); sc->carr_pending_cnt = 0; ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_INTR_ENABLES, @@ -1757,14 +1757,14 @@ ADW_SCSI_REQ_Q *scsiq; * to the stopper value. The current stopper will be changed * below to point to the new stopper. */ - new_carrp->next_ba = ASC_CQ_STOPPER; + new_carrp->next_ba = htole32(ASC_CQ_STOPPER); req_size = sizeof(ADW_SCSI_REQ_Q); req_paddr = sc->sc_dmamap_control->dm_segs[0].ds_addr + ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsiq); /* Save physical address of ADW_SCSI_REQ_Q and Carrier. */ - scsiq->scsiq_rptr = req_paddr; + scsiq->scsiq_rptr = htole32(req_paddr); /* * Every ADV_CARR_T.carr_ba is byte swapped to little-endian @@ -1778,7 +1778,7 @@ ADW_SCSI_REQ_Q *scsiq; * the microcode. The newly allocated stopper will become the new * stopper. */ - sc->icq_sp->areq_ba = req_paddr; + sc->icq_sp->areq_ba = htole32(req_paddr); /* * Set the 'next_ba' pointer for the old stopper to be the @@ -1821,7 +1821,7 @@ ADW_SCSI_REQ_Q *scsiq; * address of the new carrier stopper to the COMMA register. */ ADW_WRITE_DWORD_REGISTER(iot, ioh, IOPDW_COMMA, - new_carrp->carr_ba); + le32toh(new_carrp->carr_ba)); } /* @@ -2054,7 +2054,7 @@ ADW_SOFTC *sc; /* * Check if the IRQ stopper carrier contains a completed request. */ - while (((irq_next_pa = sc->irq_sp->next_ba) & ASC_RQ_DONE) != 0) + while (((le32toh(irq_next_pa = sc->irq_sp->next_ba)) & ASC_RQ_DONE) != 0) { #if ADW_DEBUG printf("irq 0x%x, 0x%x, 0x%x, 0x%x\n", @@ -2082,7 +2082,7 @@ ADW_SOFTC *sc; * DMAed to host memory by the firmware. Set all status fields * to indicate good status. */ - if ((irq_next_pa & ASC_RQ_GOOD) != 0) { + if ((le32toh(irq_next_pa) & ASC_RQ_GOOD) != 0) { scsiq->done_status = QD_NO_ERROR; scsiq->host_status = scsiq->scsi_status = 0; scsiq->data_cnt = 0L; diff --git a/sys/dev/ic/adwmcode.h b/sys/dev/ic/adwmcode.h index e0a5cb59a41a..9529417058b5 100644 --- a/sys/dev/ic/adwmcode.h +++ b/sys/dev/ic/adwmcode.h @@ -1,4 +1,4 @@ -/* $NetBSD: adwmcode.h,v 1.6 2001/01/18 20:28:17 jdolecek Exp $ */ +/* $NetBSD: adwmcode.h,v 1.7 2001/08/29 17:25:04 briggs Exp $ */ /* * Generic driver definitions and exported functions for the Advanced @@ -77,21 +77,21 @@ typedef struct adw_carrier ADW_CARRIER; * Mask used to eliminate low 4 bits of carrier 'next_ba' field. */ #define ASC_NEXT_BA_MASK 0xFFFFFFF0 -#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_BA_MASK) +#define ASC_GET_CARRP(carrp) htole32((le32toh(carrp)) & ASC_NEXT_BA_MASK) /* * Bus Address of a Carrier. * ba = base_ba + v_address - base_va */ -#define ADW_CARRIER_BADDR(dmamap, carriers, x) ((dmamap)->dm_segs[0].ds_addr +\ - (((u_long)x) - ((u_long)(carriers)))) +#define ADW_CARRIER_BADDR(dmamap, carriers, x) \ + htole32((dmamap)->dm_segs[0].ds_addr + ((u_long)x - (u_long)(carriers))) /* * Virtual Address of a Carrier. * va = base_va + bus_address - base_ba */ #define ADW_CARRIER_VADDR(sc, x) ((ADW_CARRIER *) \ (((u_int8_t *)(sc)->sc_control->carriers) + \ - ((u_long)x) - \ + le32toh((u_long)x) - \ (sc)->sc_dmamap_carrier->dm_segs[0].ds_addr)) /******************************************************************************/