Index: arch/hp300/conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/conf/GENERIC,v retrieving revision 1.93 diff -u -r1.93 GENERIC --- arch/hp300/conf/GENERIC 2003/05/24 06:21:21 1.93 +++ arch/hp300/conf/GENERIC 2003/07/06 04:32:32 @@ -218,11 +218,17 @@ mt* at hpibbus? slave ? punit ? # HP-IB 9-track tape ppi0 at hpibbus0 slave 5 punit 0 # HP-IB plotter -oscsi* at dio? scode ? # Old HP SCSI +#oscsi* at dio? scode ? # Old HP SCSI -sd* at oscsi? target ? lun ? # SCSI disks -st* at oscsi? target ? lun ? # SCSI tapes -ac* at oscsi? target ? lun ? # SCSI changers +#sd* at oscsi? target ? lun ? # SCSI disks +#st* at oscsi? target ? lun ? # SCSI tapes +#ac* at oscsi? target ? lun ? # SCSI changers + +spc* at dio? scode ? +scsibus* at spc? +sd* at scsibus? target ? lun ? +cd* at scsibus? target ? lun ? +st* at scsibus? target ? lun ? # # Pseudo-devices Index: arch/hp300/conf/files.hp300 =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/conf/files.hp300,v retrieving revision 1.66 diff -u -r1.66 files.hp300 --- arch/hp300/conf/files.hp300 2003/06/28 08:22:02 1.66 +++ arch/hp300/conf/files.hp300 2003/07/06 04:32:33 @@ -170,23 +170,31 @@ file arch/hp300/dev/ppi.c ppi needs-flag # Old HP SCSI layer -device oscsi { target = -1, lun = -1 } -attach oscsi at dio -file arch/hp300/dev/scsi.c oscsi +#device oscsi { target = -1, lun = -1 } +#attach oscsi at dio +#file arch/hp300/dev/scsi.c oscsi # Old HP SCSI devices -device sd: disk -attach sd at oscsi -file arch/hp300/dev/sd.c sd needs-flag -file arch/hp300/dev/sd_compat.c sd # XXX +#device sd: disk +#attach sd at oscsi +#file arch/hp300/dev/sd.c sd needs-flag +#file arch/hp300/dev/sd_compat.c sd # XXX -device st: tape -attach st at oscsi -file arch/hp300/dev/st.c st needs-flag +#device st: tape +#attach st at oscsi +#file arch/hp300/dev/st.c st needs-flag -device ac -attach ac at oscsi -file arch/hp300/dev/ac.c ac needs-flag +#device ac +#attach ac at oscsi +#file arch/hp300/dev/ac.c ac needs-flag + +# MI SCSI +include "dev/scsipi/files.scsipi" + +device spc: scsi +attach spc at dio +file arch/hp300/dev/spc.c spc needs-flag +file dev/ic/mb89352.c spc # Memory Disk for ramdisk file dev/md_root.c memory_disk_hooks Index: arch/hp300/dev/dio.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/dev/dio.c,v retrieving revision 1.23 diff -u -r1.23 dio.c --- arch/hp300/dev/dio.c 2003/05/24 06:21:22 1.23 +++ arch/hp300/dev/dio.c 2003/07/06 04:32:33 @@ -69,6 +69,10 @@ #include "locators.h" #define diocf_scode cf_loc[DIOCF_SCODE] +struct dio_softc { + struct device sc_dev; + struct bus_space_tag sc_tag; +}; static int dio_scodesize __P((struct dio_attach_args *)); char *dio_devinfo __P((struct dio_attach_args *, char *, size_t)); @@ -78,7 +82,7 @@ int dioprint __P((void *, const char *)); int diosubmatch __P((struct device *, struct cfdata *, void *)); -CFATTACH_DECL(dio, sizeof(struct device), +CFATTACH_DECL(dio, sizeof(struct dio_softc), diomatch, dioattach, NULL, NULL); int @@ -102,12 +106,17 @@ struct device *parent, *self; void *aux; { + struct dio_softc *sc = (struct dio_softc *)self; struct dio_attach_args da; caddr_t pa, va; + bus_space_tag_t bst = &sc->sc_tag; int scode, scmax, scodesize; printf("\n"); + memset(bst, 0, sizeof(struct bus_space_tag)); + bst->bustype = HP300_BUS_SPACE_DIO; + scmax = DIO_SCMAX(machineid); for (scode = 0; scode < scmax; ) { @@ -138,7 +147,7 @@ /* Fill out attach args. */ memset(&da, 0, sizeof(da)); - da.da_bst = HP300_BUS_SPACE_DIO; + da.da_bst = bst; da.da_scode = scode; da.da_id = DIO_ID(va); @@ -321,4 +330,200 @@ if (priority == IPL_BIO) dmacomputeipl(); +} + +/* + * DIO specific bus_space(9) support functions. + */ +static u_int8_t dio_bus_space_read_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t)); +static void dio_bus_space_write_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t)); + +static void dio_bus_space_read_multi_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t *, bus_size_t)); +static void dio_bus_space_write_multi_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, const u_int8_t *, bus_size_t)); + +static void dio_bus_space_read_region_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t *, bus_size_t)); +static void dio_bus_space_write_region_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, const u_int8_t *, bus_size_t)); + +static void dio_bus_space_set_multi_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t, bus_size_t)); + +static void dio_bus_space_set_region_odd_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t, bus_size_t)); + +/* + * dio_set_bus_space_oddbyte(): + * Override bus_space functions in bus_space_tag_t + * for devices which have odd byte address space. + */ +void +dio_set_bus_space_oddbyte(bst) + bus_space_tag_t bst; +{ + + /* XXX only 1-byte functions for now */ + bst->bsr1 = dio_bus_space_read_odd_1; + bst->bsw1 = dio_bus_space_write_odd_1; + + bst->bsrm1 = dio_bus_space_read_multi_odd_1; + bst->bswm1 = dio_bus_space_write_multi_odd_1; + + bst->bsrr1 = dio_bus_space_read_region_odd_1; + bst->bswr1 = dio_bus_space_write_region_odd_1; + + bst->bssm1 = dio_bus_space_set_multi_odd_1; + + bst->bssr1 = dio_bus_space_set_region_odd_1; +} + +static u_int8_t +dio_bus_space_read_odd_1(bst, bsh, offset) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; +{ + + return *(volatile u_int8_t *)(bsh + (offset << 1) + 1); +} + +static void dio_bus_space_write_odd_1(bst, bsh, offset, val) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t val; +{ + + *(volatile u_int8_t *)(bsh + (offset << 1) + 1) = val; +} + +static void +dio_bus_space_read_multi_odd_1(bst, bsh, offset, addr, len) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t *addr; + bus_size_t len; +{ + + __asm __volatile ( + " movl %0,%%a0 ;\n" + " movl %1,%%a1 ;\n" + " movl %2,%%d0 ;\n" + "1: movb %%a0@,%%a1@+ ;\n" + " subql #1,%%d0 ;\n" + " jne 1b" + : + : "r" (bsh + (offset << 1) + 1), "g" (addr), "g" (len) + : "%a0","%a1","%d0"); +} + +static void +dio_bus_space_write_multi_odd_1(bst, bsh, offset, addr, len) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; + const u_int8_t *addr; + bus_size_t len; +{ + + __asm __volatile ( + " movl %0,%%a0 ;\n" + " movl %1,%%a1 ;\n" + " movl %2,%%d0 ;\n" + "1: movb %%a1@+,%%a0@ ;\n" + " subql #1,%%d0 ;\n" + " jne 1b" + : + : "r" (bsh + (offset << 1) + 1), "g" (addr), "g" (len) + : "%a0","%a1","%d0"); +} + +static void +dio_bus_space_read_region_odd_1(bst, bsh, offset, addr, len) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t *addr; + bus_size_t len; +{ + __asm __volatile ( + " movl %0,%%a0 ;\n" + " movl %1,%%a1 ;\n" + " movl %2,%%d0 ;\n" + "1: movb %%a0@,%%a1@+ ;\n" + " addql #2,%%a0 ;\n" + " subql #1,%%d0 ;\n" + " jne 1b" + : + : "r" (bsh + (offset << 1) + 1), "g" (addr), "g" (len) + : "%a0","%a1","%d0"); +} + +static void +dio_bus_space_write_region_odd_1(bst, bsh, offset, addr, len) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; + const u_int8_t *addr; + bus_size_t len; +{ + + __asm __volatile ( + " movl %0,%%a0 ;\n" + " movl %1,%%a1 ;\n" + " movl %2,%%d0 ;\n" + "1: movb %%a1@+,%%a0@ ;\n" + " addql #2,%%a0 ;\n" + " subql #1,%%d0 ;\n" + " jne 1b" + : + : "r" (bsh + (offset << 1) + 1), "g" (addr), "g" (len) + : "%a0","%a1","%d0"); +} + +static void +dio_bus_space_set_multi_odd_1(bst, bsh, offset, val, count) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t val; + bus_size_t count; +{ + __asm __volatile ( + " movl %0,%%a0 ;\n" + " movl %1,%%d1 ;\n" + " movl %2,%%d0 ;\n" + "1: movb %%d1,%%a0@ ;\n" + " subql #1,%%d0 ;\n" + " jne 1b" + : + : "r" (bsh + (offset << 1) + 1), "g" (val), "g" (count) + : "%a0","%d0","%d1"); +} + +static void +dio_bus_space_set_region_odd_1(bst, bsh, offset, val, count) + bus_space_tag_t bst; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t val; + bus_size_t count; +{ + + __asm __volatile ( + " movl %0,%%a0 ;\n" + " movl %1,%%d1 ;\n" + " movl %2,%%d0 ;\n" + "1: movb %%d1,%%a0@ ;\n" + " addql #2,%%a0 ;\n" + " subql #1,%%d0 ;\n" + " jne 1b" + : + : "r" (bsh + (offset << 1) + 1), "g" (val), "g" (count) + : "%a0","%d0","%d1"); } Index: arch/hp300/dev/diovar.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/dev/diovar.h,v retrieving revision 1.8 diff -u -r1.8 diovar.h --- arch/hp300/dev/diovar.h 2003/05/24 06:21:22 1.8 +++ arch/hp300/dev/diovar.h 2003/07/06 04:32:33 @@ -79,4 +79,5 @@ void *dio_scodetopa __P((int)); void *dio_intr_establish __P((int (*)(void *), void *, int, int)); void dio_intr_disestablish __P((void *)); +void dio_set_bus_space_oddbyte __P((bus_space_tag_t)); #endif /* _KERNEL */ Index: arch/hp300/dev/intio.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/dev/intio.c,v retrieving revision 1.15 diff -u -r1.15 intio.c --- arch/hp300/dev/intio.c 2003/05/24 06:21:22 1.15 +++ arch/hp300/dev/intio.c 2003/07/06 04:32:34 @@ -52,11 +52,16 @@ #include #include +struct intio_softc { + struct device sc_dev; + struct bus_space_tag sc_tag; +}; + int intiomatch(struct device *, struct cfdata *, void *); void intioattach(struct device *, struct device *, void *); int intioprint(void *, const char *); -CFATTACH_DECL(intio, sizeof(struct device), +CFATTACH_DECL(intio, sizeof(struct intio_softc), intiomatch, intioattach, NULL, NULL); #if defined(HP320) || defined(HP330) || defined(HP340) || defined(HP345) || \ @@ -107,13 +112,18 @@ struct device *parent, *self; void *aux; { + struct intio_softc *sc = (struct intio_softc *)self; struct intio_attach_args ia; const struct intio_builtins *ib; + bus_space_tag_t bst = &sc->sc_tag; int ndevs; int i; printf("\n"); + memset(bst, 0, sizeof(struct bus_space_tag)); + bst->bustype = HP300_BUS_SPACE_INTIO; + switch (machineid) { #if defined(HP320) || defined(HP330) || defined(HP340) || defined(HP345) || \ defined(HP350) || defined(HP360) || defined(HP370) || defined(HP375) || \ @@ -157,7 +167,7 @@ strncpy(ia.ia_modname, ib[i].ib_modname, INTIO_MOD_LEN); ia.ia_modname[INTIO_MOD_LEN] = '\0'; - ia.ia_bst = HP300_BUS_SPACE_INTIO; + ia.ia_bst = bst; ia.ia_iobase = ib[i].ib_offset; ia.ia_addr = (bus_addr_t)(intiobase + ib[i].ib_offset); ia.ia_ipl = ib[i].ib_ipl; Index: arch/hp300/hp300/autoconf.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/hp300/autoconf.c,v retrieving revision 1.62 diff -u -r1.62 autoconf.c --- arch/hp300/hp300/autoconf.c 2003/04/01 20:41:38 1.62 +++ arch/hp300/hp300/autoconf.c 2003/07/06 04:32:34 @@ -131,6 +131,10 @@ #include +#include +#include +#include + #include #include #include @@ -149,8 +153,6 @@ #include #include -#include - /* should go away with a cleanup */ extern int dcacnattach(bus_space_tag_t, bus_addr_t, int); @@ -435,7 +437,7 @@ if (memcmp(dev->dv_xname, "fhpib", 5) == 0 || memcmp(dev->dv_xname, "nhpib", 5) == 0 || - memcmp(dev->dv_xname, "oscsi", 5) == 0) { + memcmp(dev->dv_xname, "spc", 3) == 0) { struct dio_attach_args *da = aux; dd->dd_scode = da->da_scode; @@ -451,10 +453,10 @@ } if (memcmp(dev->dv_xname, "sd", 2) == 0) { - struct oscsi_attach_args *osa = aux; + struct scsipibus_attach_args *sa = aux; - dd->dd_slave = osa->osa_target; - dd->dd_punit = osa->osa_lun; + dd->dd_slave = sa->sa_periph->periph_target; + dd->dd_punit = sa->sa_periph->periph_lun; goto linkup; } @@ -473,7 +475,7 @@ return; } - if (memcmp(dev->dv_xname, "oscsi", 5) == 0) { + if (memcmp(dev->dv_xname, "spc", 3) == 0) { dev_data_insert(dd, &dev_data_list_scsi); return; } @@ -603,23 +605,11 @@ for (dd = dev_data_list.lh_first; dd != NULL; dd = dd->dd_list.le_next) { /* - * XXX We don't yet have the extra bus indirection - * XXX for SCSI, so we have to do a little bit of - * XXX extra work. + * "sd" -> "scsibus" -> "spc" + * "rd" -> "hpibbus" -> "fhpib" */ - if (memcmp(dd->dd_dev->dv_xname, "sd", 2) == 0) { - /* - * "sd" -> "oscsi" - */ - if (dd->dd_dev->dv_parent != cdd->dd_dev) - continue; - } else { - /* - * "rd" -> "hpibbus" -> "fhpib" - */ - if (dd->dd_dev->dv_parent->dv_parent != cdd->dd_dev) - continue; - } + if (dd->dd_dev->dv_parent->dv_parent != cdd->dd_dev) + continue; if (dd->dd_slave == slave && dd->dd_punit == punit) { @@ -686,9 +676,11 @@ * Get parent's info. */ switch (type) { - case 2: + case 2: /* rd */ + case 4: /* sd */ /* * "rd" -> "hpibbus" -> "fhpib" + * "sd" -> "scsibus" -> "spc" */ for (cdd = dev_data_list_hpib.lh_first, ctlr = 0; cdd != NULL; cdd = cdd->dd_clist.le_next, ctlr++) { @@ -703,24 +695,6 @@ } } break; - - case 4: - /* - * "sd" -> "oscsi" - */ - for (cdd = dev_data_list_scsi.lh_first, ctlr = 0; - cdd != NULL; cdd = cdd->dd_clist.le_next, ctlr++) { - if (cdd->dd_dev == root_device->dv_parent) { - /* - * Found it! - */ - bootdev = MAKEBOOTDEV(type, - ctlr, dd->dd_slave, dd->dd_punit, - DISKPART(rootdev)); - break; - } - } - break; } out: @@ -801,11 +775,18 @@ void hp300_cninit() { + struct bus_space_tag tag; + bus_space_tag_t bst; + + bst = &tag; + memset(bst, 0, sizeof(struct bus_space_tag)); + bst->bustype = HP300_BUS_SPACE_INTIO; + /* * Look for serial consoles first. */ #if NAPCI > 0 - if (!apcicnattach(HP300_BUS_SPACE_INTIO, 0x1c020, -1)) + if (!apcicnattach(bst, 0x1c020, -1)) return; #endif #if NDCA > 0 @@ -823,19 +804,19 @@ * Look for internal framebuffers. */ #if NDVBOX > 0 - if (!dvboxcnattach(HP300_BUS_SPACE_INTIO, 0x160000,-1)) + if (!dvboxcnattach(bst, 0x160000,-1)) goto find_kbd; #endif #if NGBOX > 0 - if (!gboxcnattach(HP300_BUS_SPACE_INTIO, 0x160000,-1)) + if (!gboxcnattach(bst, 0x160000,-1)) goto find_kbd; #endif #if NRBOX > 0 - if (!rboxcnattach(HP300_BUS_SPACE_INTIO, 0x160000,-1)) + if (!rboxcnattach(bst, 0x160000,-1)) goto find_kbd; #endif #if NTOPCAT > 0 - if (!topcatcnattach(HP300_BUS_SPACE_INTIO, 0x160000,-1)) + if (!topcatcnattach(bst, 0x160000,-1)) goto find_kbd; #endif #endif /* CONSCODE */ @@ -867,11 +848,11 @@ find_kbd: #if NDNKBD > 0 - dnkbdcnattach(HP300_BUS_SPACE_INTIO, 0x1c000) + dnkbdcnattach(bst, 0x1c000) #endif #if NHIL > 0 - hilkbdcnattach(HP300_BUS_SPACE_INTIO, 0x28000); + hilkbdcnattach(bst, 0x28000); #endif #endif /* NITE */ } @@ -903,8 +884,13 @@ int scode; int (*func)(bus_space_tag_t, bus_addr_t, int); { + struct bus_space_tag tag; + bus_space_tag_t bst; caddr_t pa, va; + bst = &tag; + memset(bst, 0, sizeof(struct bus_space_tag)); + bst->bustype = HP300_BUS_SPACE_DIO; pa = dio_scodetopa(scode); va = iomap(pa, PAGE_SIZE); if (va == 0) @@ -915,7 +901,7 @@ } iounmap(va, PAGE_SIZE); - return ((*func)(HP300_BUS_SPACE_DIO, (bus_addr_t)pa, scode)); + return ((*func)(bst, (bus_addr_t)pa, scode)); } Index: arch/hp300/hp300/bus_space.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/hp300/bus_space.c,v retrieving revision 1.6 diff -u -r1.6 bus_space.c --- arch/hp300/hp300/bus_space.c 2002/09/27 15:36:02 1.6 +++ arch/hp300/hp300/bus_space.c 2003/07/06 04:32:34 @@ -67,7 +67,7 @@ u_long kva; int error; - if (t == HP300_BUS_SPACE_INTIO) { + if (t->bustype == HP300_BUS_SPACE_INTIO) { /* * Intio space is direct-mapped in pmap_bootstrap(); just * do the translation. @@ -76,7 +76,7 @@ return (0); } - if (t != HP300_BUS_SPACE_DIO) + if (t->bustype != HP300_BUS_SPACE_DIO) panic("bus_space_map: bad space tag"); /* @@ -140,7 +140,7 @@ bus_size_t size; { - if (t == HP300_BUS_SPACE_INTIO) { + if (t->bustype == HP300_BUS_SPACE_INTIO) { /* * Intio space is direct-mapped in pmap_bootstrap(); nothing * to do @@ -148,7 +148,7 @@ return; } - if (t != HP300_BUS_SPACE_DIO) + if (t->bustype != HP300_BUS_SPACE_DIO) panic("bus_space_map: bad space tag"); size = m68k_round_page(size); Index: arch/hp300/include/bus.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/include/bus.h,v retrieving revision 1.6 diff -u -r1.6 bus.h --- arch/hp300/include/bus.h 2001/12/02 01:20:33 1.6 +++ arch/hp300/include/bus.h 2003/07/06 04:32:35 @@ -81,10 +81,69 @@ /* * Access methods for bus resources and address space. */ -typedef int bus_space_tag_t; -typedef u_long bus_space_handle_t; +typedef struct bus_space_tag *bus_space_tag_t; +typedef u_long bus_space_handle_t; /* + * Implementation specific structures. + * XXX Don't use outside of bus_space definitions! + * XXX maybe this should be encapsuled in a non-global .h file? + */ + +struct bus_space_tag { + u_int bustype; + + u_int8_t (*bsr1) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t)); + u_int16_t (*bsr2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t)); + u_int32_t (*bsr4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t)); + void (*bsrm1) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t *, bus_size_t)); + void (*bsrm2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t *, bus_size_t)); + void (*bsrm4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t *, bus_size_t)); + void (*bsrr1) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t *, bus_size_t)); + void (*bsrr2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t *, bus_size_t)); + void (*bsrr4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t *, bus_size_t)); + void (*bsw1) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t)); + void (*bsw2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t)); + void (*bsw4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t)); + void (*bswm1) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, const u_int8_t *, bus_size_t)); + void (*bswm2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, const u_int16_t *, bus_size_t)); + void (*bswm4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, const u_int32_t *, bus_size_t)); + void (*bswr1) __P((bus_space_tag_t, bus_space_handle_t , + bus_size_t, const u_int8_t *, bus_size_t)); + void (*bswr2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, const u_int16_t *, bus_size_t)); + void (*bswr4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, const u_int32_t *, bus_size_t)); + void (*bssm1) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t, bus_size_t)); + void (*bssm2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t, bus_size_t)); + void (*bssm4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t, bus_size_t)); + void (*bssr1) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t, bus_size_t)); + void (*bssr2) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int16_t, bus_size_t)); + void (*bssr4) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int32_t, bus_size_t)); +}; + +/* * int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr, * bus_size_t size, int flags, bus_space_handle_t *bshp)); * @@ -93,7 +152,7 @@ #define BUS_SPACE_MAP_CACHEABLE 0x01 #define BUS_SPACE_MAP_LINEAR 0x02 -#define BUS_SPACE_MAP_PREFETCHABLE 0x04 +#define BUS_SPACE_MAP_PREFETCHABLE 0x04 int bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t, int, bus_space_handle_t *)); @@ -173,13 +232,16 @@ */ #define bus_space_read_1(t, h, o) \ - ((void) t, (*(volatile u_int8_t *)((h) + (o)))) + (((t)->bsr1 != NULL) ? ((t)->bsr1)(t, h, o) : \ + (*(volatile u_int8_t *)((h) + (o)))) #define bus_space_read_2(t, h, o) \ - ((void) t, (*(volatile u_int16_t *)((h) + (o)))) + (((t)->bsr2 != NULL) ? ((t)->bsr2)(t, h, o) : \ + (*(volatile u_int16_t *)((h) + (o)))) #define bus_space_read_4(t, h, o) \ - ((void) t, (*(volatile u_int32_t *)((h) + (o)))) + (((t)->bsr4 != NULL) ? ((t)->bsr4)(t, h, o) : \ + (*(volatile u_int32_t *)((h) + (o)))) #if 0 /* Cause a link error for bus_space_read_8 */ #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! @@ -193,48 +255,59 @@ * Read `count' 1, 2, 4, or 8 byte quantities from bus space * described by tag/handle/offset and copy into buffer provided. */ - -#define bus_space_read_multi_1(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movb %%a0@,%%a1@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) -#define bus_space_read_multi_2(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movw %%a0@,%%a1@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) +#define bus_space_read_multi_1(t, h, o, a, c) \ +do { \ + if ((t)->bsrm1 != NULL) \ + ((t)->bsrm1)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movb %%a0@,%%a1@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_read_multi_2(t, h, o, a, c) \ +do { \ + if ((t)->bsrm2 != NULL) \ + ((t)->bsrm2)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movw %%a0@,%%a1@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) #define bus_space_read_multi_4(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movl %%a0@,%%a1@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) + if ((t)->bsrm4 != NULL) \ + ((t)->bsrm4)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movl %%a0@,%%a1@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) #if 0 /* Cause a link error for bus_space_read_multi_8 */ #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! @@ -249,48 +322,60 @@ * described by tag/handle and starting at `offset' and copy into * buffer provided. */ - -#define bus_space_read_region_1(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movb %%a0@+,%%a1@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) -#define bus_space_read_region_2(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movw %%a0@+,%%a1@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) - -#define bus_space_read_region_4(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movl %%a0@+,%%a1@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) +#define bus_space_read_region_1(t, h, o, a, c) \ +do { \ + if ((t)->bsrr1 != NULL) \ + ((t)->bsrr1)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movb %%a0@+,%%a1@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_read_region_2(t, h, o, a, c) \ +do { \ + if ((t)->bsrr2 != NULL) \ + ((t)->bsrr2)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movw %%a0@+,%%a1@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_read_region_4(t, h, o, a, c) \ +do { \ + if ((t)->bsrr4 != NULL) \ + ((t)->bsrr4)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movl %%a0@+,%%a1@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) #if 0 /* Cause a link error for bus_space_read_region_8 */ #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! @@ -306,13 +391,28 @@ */ #define bus_space_write_1(t, h, o, v) \ - ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)) = (v)))) +do { \ + if ((t)->bsw1 != NULL) \ + ((t)->bsw1)(t, h, o, v); \ + else \ + ((void)(*(volatile u_int8_t *)((h) + (o)) = (v))); \ +} while (/* CONSTCOND */ 0) #define bus_space_write_2(t, h, o, v) \ - ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)) = (v)))) +do { \ + if ((t)->bsw2 != NULL) \ + ((t)->bsw2)(t, h, o, v); \ + else \ + ((void)(*(volatile u_int16_t *)((h) + (o)) = (v))); \ +} while (/* CONSTCOND */ 0) #define bus_space_write_4(t, h, o, v) \ - ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v)))) +do { \ + if ((t)->bsw4 != NULL) \ + ((t)->bsw4)(t, h, o, v); \ + else \ + ((void)(*(volatile u_int32_t *)((h) + (o)) = (v))); \ +} while (/* CONSTCOND */ 0) #if 0 /* Cause a link error for bus_space_write_8 */ #define bus_space_write_8 !!! bus_space_write_8 not implemented !!! @@ -326,48 +426,61 @@ * Write `count' 1, 2, 4, or 8 byte quantities from the buffer * provided to bus space described by tag/handle/offset. */ - -#define bus_space_write_multi_1(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movb %%a1@+,%%a0@ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) - -#define bus_space_write_multi_2(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movw %%a1@+,%%a0@ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) -#define bus_space_write_multi_4(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movl %%a1@+,%%a0@ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) +#define bus_space_write_multi_1(t, h, o, a, c) \ +do { \ + if ((t)->bswm1 != NULL) \ + ((t)->bswm1)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movb %%a1@+,%%a0@ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_write_multi_2(t, h, o, a, c) \ +do { \ + if ((t)->bswm2 != NULL) \ + ((t)->bswm2)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movw %%a1@+,%%a0@ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_write_multi_4(t, h, o, a, c) \ +do { \ + (void) t; \ + if ((t)->bswm4 != NULL) \ + ((t)->bswm4)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movl %%a1@+,%%a0@ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) #if 0 /* Cause a link error for bus_space_write_8 */ #define bus_space_write_multi_8(t, h, o, a, c) \ @@ -383,47 +496,59 @@ * to bus space described by tag/handle starting at `offset'. */ -#define bus_space_write_region_1(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movb %%a1@+,%%a0@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) - -#define bus_space_write_region_2(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movw %%a1@+,%%a0@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) - -#define bus_space_write_region_4(t, h, o, a, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%a1 ; \ - movl %2,%%d0 ; \ - 1: movl %%a1@+,%%a0@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (a), "g" (c) : \ - "%a0","%a1","%d0"); \ -} while (0) +#define bus_space_write_region_1(t, h, o, a, c) \ +do { \ + if ((t)->bswr1 != NULL) \ + ((t)->bswr1)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movb %%a1@+,%%a0@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_write_region_2(t, h, o, a, c) \ +do { \ + if ((t)->bswr2) != NULL) \ + ((t)->bswr2)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movw %%a1@+,%%a0@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_write_region_4(t, h, o, a, c) \ +do { \ + if ((t)->bswr4) != NULL) \ + ((t)->bswr4)(t, h, o, a, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%a1 ; \ + movl %2,%%d0 ; \ + 1: movl %%a1@+,%%a0@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (a), "g" (c) : \ + "%a0","%a1","%d0"); \ + } \ +} while (/* CONSTCOND */ 0) #if 0 /* Cause a link error for bus_space_write_region_8 */ #define bus_space_write_region_8 \ @@ -438,49 +563,61 @@ * Write the 1, 2, 4, or 8 byte value `val' to bus space described * by tag/handle/offset `count' times. */ - -#define bus_space_set_multi_1(t, h, o, val, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%d1 ; \ - movl %2,%%d0 ; \ - 1: movb %%d1,%%a0@ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (val), "g" (c) : \ - "%a0","%d0","%d1"); \ -} while (0) -#define bus_space_set_multi_2(t, h, o, val, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%d1 ; \ - movl %2,%%d0 ; \ - 1: movw %%d1,%%a0@ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (val), "g" (c) : \ - "%a0","%d0","%d1"); \ -} while (0) +#define bus_space_set_multi_1(t, h, o, val, c) \ +do { \ + if ((t)->bssm1 != NULL) \ + ((t)->bssm1)(t, h, o, val, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%d1 ; \ + movl %2,%%d0 ; \ + 1: movb %%d1,%%a0@ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (val), "g" (c) : \ + "%a0","%d0","%d1"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_set_multi_2(t, h, o, val, c) \ +do { \ + if ((t)->bssm2 != NULL) \ + ((t)->bssm2)(t, h, o, val, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%d1 ; \ + movl %2,%%d0 ; \ + 1: movw %%d1,%%a0@ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (val), "g" (c) : \ + "%a0","%d0","%d1"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_set_multi_4(t, h, o, val, c) \ +do { \ + if ((t)->bssm4 != NULL) \ + ((t)->bssm4)(t, h, o, val, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%d1 ; \ + movl %2,%%d0 ; \ + 1: movl %%d1,%%a0@ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (val), "g" (c) : \ + "%a0","%d0","%d1"); \ + } \ +} while (/* CONSTCOND */ 0) -#define bus_space_set_multi_4(t, h, o, val, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%d1 ; \ - movl %2,%%d0 ; \ - 1: movl %%d1,%%a0@ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (val), "g" (c) : \ - "%a0","%d0","%d1"); \ -} while (0) - #if 0 /* Cause a link error for bus_space_set_multi_8 */ #define bus_space_set_multi_8 \ !!! bus_space_set_multi_8 unimplemented !!! @@ -494,48 +631,61 @@ * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described * by tag/handle starting at `offset'. */ - -#define bus_space_set_region_1(t, h, o, val, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%d1 ; \ - movl %2,%%d0 ; \ - 1: movb %%d1,%%a0@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (val), "g" (c) : \ - "%a0","%d0","%d1"); \ -} while (0) -#define bus_space_set_region_2(t, h, o, val, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%d1 ; \ - movl %2,%%d0 ; \ - 1: movw %%d1,%%a0@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (val), "g" (c) : \ - "%a0","%d0","%d1"); \ -} while (0) - -#define bus_space_set_region_4(t, h, o, val, c) do { \ - (void) t; \ - __asm __volatile (" \ - movl %0,%%a0 ; \ - movl %1,%%d1 ; \ - movl %2,%%d0 ; \ - 1: movl %%d1,%%a0@+ ; \ - subql #1,%%d0 ; \ - jne 1b" : \ - : \ - "r" ((h) + (o)), "g" (val), "g" (c) : \ - "%a0","%d0","%d1"); \ -} while (0) +#define bus_space_set_region_1(t, h, o, val, c) \ +do { \ + if ((t)->bssr1 != NULL) \ + ((t)->bssr1)(t, h, o, val, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%d1 ; \ + movl %2,%%d0 ; \ + 1: movb %%d1,%%a0@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (val), "g" (c) : \ + "%a0","%d0","%d1"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_set_region_2(t, h, o, val, c) \ +do { \ + if ((t)->bssr2 != NULL) \ + ((t)->bssr2)(t, h, o, val, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%d1 ; \ + movl %2,%%d0 ; \ + 1: movw %%d1,%%a0@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (val), "g" (c) : \ + "%a0","%d0","%d1"); \ + } \ +} while (/* CONSTCOND */ 0) + +#define bus_space_set_region_4(t, h, o, val, c) \ +do { \ + (void) t; \ + if ((t)->bssr4 != NULL) \ + ((t)->bssr4)(t, h, o, val, c); \ + else { \ + __asm __volatile (" \ + movl %0,%%a0 ; \ + movl %1,%%d1 ; \ + movl %2,%%d0 ; \ + 1: movl %%d1,%%a0@+ ; \ + subql #1,%%d0 ; \ + jne 1b" : \ + : \ + "r" ((h) + (o)), "g" (val), "g" (c) : \ + "%a0","%d0","%d1"); \ + } \ +} while (/* CONSTCOND */ 0) #if 0 /* Cause a link error for bus_space_set_region_8 */ #define bus_space_set_region_8 \ @@ -555,9 +705,9 @@ #define __HP300_copy_region_N(BYTES) \ static __inline void __CONCAT(bus_space_copy_region_,BYTES) \ __P((bus_space_tag_t, \ - bus_space_handle_t bsh1, bus_size_t off1, \ - bus_space_handle_t bsh2, bus_size_t off2, \ - bus_size_t count)); \ + bus_space_handle_t, bus_size_t, \ + bus_space_handle_t, bus_size_t, \ + bus_size_t)); \ \ static __inline void \ __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \ Index: dev/ic/mb89352.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/mb89352.c,v retrieving revision 1.20 diff -u -r1.20 mb89352.c --- dev/ic/mb89352.c 2003/07/05 19:50:17 1.20 +++ dev/ic/mb89352.c 2003/07/06 04:32:36 @@ -117,6 +117,9 @@ #define SPC_ABORT_TIMEOUT 2000 /* time to wait for abort */ +/* threshold length for DMA transfer */ +#define SPC_MIN_DMA_LEN 32 + /* End of customizable parameters */ /* @@ -545,8 +548,19 @@ /* XXX Not supported. */ return; case ADAPTER_REQ_SET_XFER_MODE: - /* XXX Not supported. */ + { + /* + * We don't support Sync, Wide, or Tagged Command Queuing. + * Just callback now, to report this. + */ + struct scsipi_xfer_mode *xm = arg; + + xm->xm_mode = 0; + xm->xm_period = 0; + xm->xm_offset = 0; + scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm); return; + } } } @@ -658,9 +672,10 @@ * X = 2 + 113 / 256 * ==> tch = 2, tcm = 113 (correct?) */ + /* Time to the information transfer phase start. */ + /* XXX These values should be calculated from sc_freq */ bus_space_write_1(iot, ioh, TCH, 2); bus_space_write_1(iot, ioh, TCM, 113); - /* Time to the information transfer phase start. */ bus_space_write_1(iot, ioh, TCL, 3); bus_space_write_1(iot, ioh, SCMD, SCMD_SELECT); @@ -1592,6 +1607,17 @@ SPC_TRACE(("spc_intr ")); + ints = bus_space_read_1(iot, ioh, INTS); + if (ints == 0) + goto out; + + if (sc->sc_dma_done != NULL && + sc->sc_state == SPC_CONNECTED && + (sc->sc_flags & SPC_DOINGDMA) != 0 && + (sc->sc_phase == PH_DATAOUT || sc->sc_phase == PH_DATAIN)) { + (*sc->sc_dma_done)(sc); + } + loop: /* * Loop until transfer completion. @@ -1898,6 +1924,12 @@ if (sc->sc_state != SPC_CONNECTED) break; SPC_MISC(("dataout dleft=%d ", sc->sc_dleft)); + if (sc->sc_dma_start != NULL && + sc->sc_dleft > SPC_MIN_DMA_LEN) { + (*sc->sc_dma_start)(sc, sc->sc_dp, sc->sc_dleft, 0); + sc->sc_prevphase = PH_DATAOUT; + goto out; + } n = spc_dataout_pio(sc, sc->sc_dp, sc->sc_dleft); sc->sc_dp += n; sc->sc_dleft -= n; @@ -1908,6 +1940,12 @@ if (sc->sc_state != SPC_CONNECTED) break; SPC_MISC(("datain ")); + if (sc->sc_dma_start != NULL && + sc->sc_dleft > SPC_MIN_DMA_LEN) { + (*sc->sc_dma_start)(sc, sc->sc_dp, sc->sc_dleft, 1); + sc->sc_prevphase = PH_DATAIN; + goto out; + } n = spc_datain_pio(sc, sc->sc_dp, sc->sc_dleft); sc->sc_dp += n; sc->sc_dleft -= n; Index: dev/ic/mb89352var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/mb89352var.h,v retrieving revision 1.4 diff -u -r1.4 mb89352var.h --- dev/ic/mb89352var.h 2003/07/05 19:00:16 1.4 +++ dev/ic/mb89352var.h 2003/07/06 04:32:37 @@ -144,7 +144,7 @@ u_char sc_flags; #define SPC_DROP_MSGIN 0x01 /* Discard all msgs (parity err detected) */ #define SPC_ABORTING 0x02 /* Bailing out */ -#define SPC_DOINGDMA 0x04 /* The FIFO data path is active! */ +#define SPC_DOINGDMA 0x04 /* doing DMA */ #define SPC_INACTIVE 0x80 /* The FIFO data path is active! */ u_char sc_selid; /* Reselection ID */ @@ -172,6 +172,10 @@ int sc_freq; /* Clock frequency in MHz */ int sc_minsync; /* Minimum sync period / 4 */ int sc_maxsync; /* Maximum sync period / 4 */ + + /* DMA function set from MD code */ + void (*sc_dma_start)(struct spc_softc *, void *, size_t, int); + void (*sc_dma_done)(struct spc_softc *); }; #if SPC_DEBUG --- /dev/null 2003-07-06 13:20:52.000000000 +0900 +++ arch/hp300/dev/hp98265reg.h 2003-07-06 02:59:34.000000000 +0900 @@ -0,0 +1,74 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Van Jacobson of Lawrence Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)scsireg.h 8.1 (Berkeley) 6/10/93 + */ + +/* + * HP 98265A SCSI Interface Hardware Description. + */ + +#define SPC_OFFSET 32 +#define SPC_SIZE (32 * 2) /* XXX */ + +#define HPSCSI_ID 0x00 +#define ID_MASK 0x1f +#define SCSI_ID 0x07 +#define ID_WORD_DMA 0x20 + +#define HPSCSI_CSR 0x01 +#define CSR_IE 0x80 +#define CSR_IR 0x40 +#define SCSI_IPL(csr) ((((csr) >> 4) & 3) + 3) +#define CSR_DMA32 0x08 +#define CSR_DMAIN 0x04 +#define CSR_DE1 0x02 +#define CSR_DE0 0x01 + +#define HPSCSI_WRAP 0x02 +#define WRAP_REQ 0x80 +#define WRAP_ACK 0x40 +#define WRAP_BSY 0x08 +#define WRAP_MSG 0x04 +#define WRAP_CD 0x02 +#define WRAP_IO 0x01 + +#define HPSCSI_HCONF 0x03 +#define HCONF_TP 0x80 +#define SCSI_SYNC_XFER(hconf) (((hconf) >> 5) & 3) +#define HCONF_SD 0x10 +#define HCONF_PARITY 0x08 --- /dev/null 2003-07-06 13:20:52.000000000 +0900 +++ arch/hp300/dev/spc.c 2003-07-06 05:13:33.000000000 +0900 @@ -0,0 +1,307 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2003 Izumi Tsutsui. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opt_ddb.h" + +#include /* RCS ID & Copyright macro defns */ + +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +static int spc_dio_match __P((struct device *, struct cfdata *, void *)); +static void spc_dio_attach __P((struct device *, struct device *, void *)); +static void spc_dio_dmastart __P((struct spc_softc *, void *, size_t, int)); +static void spc_dio_dmadone __P((struct spc_softc *)); +static void spc_dio_dmago __P((void *)); +static void spc_dio_dmastop __P((void *)); + +struct spc_dio_softc { + struct spc_softc sc_spc; /* MI spc softc */ + + /* DIO specific goo. */ + struct bus_space_tag sc_tag; /* bus space tag with oddbyte func */ + bus_space_handle_t sc_iohsc; /* bus space handle for HPSCSI */ + struct dmaqueue sc_dq; /* DMA job queue */ + u_int sc_dflags; /* DMA flags */ +#define SCSI_DMA32 0x01 /* 32-bit DMA should be used */ +#define SCSI_HAVEDMA 0x02 /* controller has DMA channel */ +#define SCSI_DATAIN 0x04 /* DMA direction */ +}; + +CFATTACH_DECL(spc, sizeof(struct spc_dio_softc), + spc_dio_match, spc_dio_attach, NULL, NULL); + +static int +spc_dio_match(parent, cf, aux) + struct device *parent; + struct cfdata *cf; + void *aux; +{ + struct dio_attach_args *da = aux; + + switch (da->da_id) { + case DIO_DEVICE_ID_SCSI0: + case DIO_DEVICE_ID_SCSI1: + case DIO_DEVICE_ID_SCSI2: + case DIO_DEVICE_ID_SCSI3: + return 1; + } + + return 0; +} + +static void +spc_dio_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct spc_dio_softc *dsc = (struct spc_dio_softc *)self; + struct spc_softc *sc = &dsc->sc_spc; + struct dio_attach_args *da = aux; + bus_space_tag_t iot = &dsc->sc_tag; + bus_space_handle_t iohsc, iohspc; + u_int8_t id; + + memcpy(iot, da->da_bst, sizeof(struct bus_space_tag)); + dio_set_bus_space_oddbyte(iot); + + if (bus_space_map(iot, (bus_addr_t)dio_scodetopa(da->da_scode), + da->da_size, 0, &iohsc)) { + printf(": can't map SCSI registers\n"); + return; + } + + if (bus_space_subregion(iot, iohsc, SPC_OFFSET, SPC_SIZE, &iohspc)) { + printf(": can't map SPC registers\n"); + return; + } + + printf(": HP 98265A SCSI"); + + bus_space_write_1(iot, iohsc, HPSCSI_ID, 0xff); + DELAY(100); + id = bus_space_read_1(iot, iohsc, HPSCSI_ID); + if ((id & ID_WORD_DMA) == 0) { + printf(", 32-bit DMA"); + dsc->sc_dflags |= SCSI_DMA32; + } + id &= ID_MASK; + printf(", SCSI ID %d\n", id); + + sc->sc_iot = iot; + sc->sc_ioh = iohspc; + sc->sc_initiator = id; + + sc->sc_dma_start = spc_dio_dmastart; + sc->sc_dma_done = spc_dio_dmadone; + + dsc->sc_iohsc = iohsc; + dsc->sc_dq.dq_softc = dsc; + dsc->sc_dq.dq_start = spc_dio_dmago; + dsc->sc_dq.dq_done = spc_dio_dmastop; + + bus_space_write_1(iot, iohsc, HPSCSI_CSR, 0x00); + bus_space_write_1(iot, iohsc, HPSCSI_HCONF, 0x00); + + dio_intr_establish(spc_intr, (void *)sc, da->da_ipl, IPL_BIO); + + spc_attach(sc); + + /* enable SPC interrupt gate(?) */ + bus_space_write_1(iot, iohsc, HPSCSI_CSR, CSR_IE); +} + +static +void spc_dio_dmastart(sc, addr, size, datain) + struct spc_softc *sc; + void *addr; + size_t size; + int datain; +{ + struct spc_dio_softc *dsc = (struct spc_dio_softc *)sc; + + dsc->sc_dq.dq_chan = DMA0 | DMA1; + dsc->sc_dflags |= SCSI_HAVEDMA; + if (datain) + dsc->sc_dflags |= SCSI_DATAIN; + else + dsc->sc_dflags &= ~SCSI_DATAIN; + + if (dmareq(&dsc->sc_dq) == 1) + /* DMA channel is available, so start DMA immediately */ + spc_dio_dmago((void *)dsc); + /* else dma start function will be called later from dmafree(). */ +} + +static +void spc_dio_dmago(arg) + void *arg; +{ + struct spc_dio_softc *dsc = (struct spc_dio_softc *)arg; + struct spc_softc *sc = &dsc->sc_spc; + bus_space_tag_t iot; + bus_space_handle_t iohsc, iohspc; + int len, chan; + u_int32_t dmaflags; + u_int8_t cmd; + + iot = sc->sc_iot; + iohspc = sc->sc_ioh; + iohsc = dsc->sc_iohsc; + + bus_space_write_1(iot, iohsc, HPSCSI_HCONF, 0); + + cmd = CSR_IE; + dmaflags = DMAGO_NOINT; + chan = dsc->sc_dq.dq_chan; + if ((dsc->sc_dflags & SCSI_DATAIN) != 0) { + cmd |= CSR_DMAIN; + dmaflags |= DMAGO_READ; + } + if ((dsc->sc_dflags & SCSI_DMA32) != 0 && + ((u_int)sc->sc_dp & 3) == 0 && + (sc->sc_dleft & 3) == 0) { + cmd |= CSR_DMA32; + dmaflags |= DMAGO_LWORD; + } else + dmaflags |= DMAGO_WORD; + + dmago(chan, sc->sc_dp, sc->sc_dleft, dmaflags); + + bus_space_write_1(iot, iohsc, HPSCSI_CSR, cmd); + cmd |= (chan == 0) ? CSR_DE0 : CSR_DE1; + bus_space_write_1(iot, iohsc, HPSCSI_CSR, cmd); + + cmd = SCMD_XFR; + len = sc->sc_dleft; + + if ((len & (DEV_BSIZE - 1)) != 0) /* XXX ??? */ { + cmd |= SCMD_PAD; +#if 0 + if ((dsc->sc_dflags & SCSI_DATAIN) != 0) + len += 2; /* XXX ??? */ +#endif + } + + bus_space_write_1(iot, iohspc, TCH, len >> 16); + bus_space_write_1(iot, iohspc, TCM, len >> 8); + bus_space_write_1(iot, iohspc, TCL, len); + bus_space_write_1(iot, iohspc, PCTL, sc->sc_phase | PCTL_BFINT_ENAB); +#if 0 + bus_space_write_1(iot, iohspc, TMOD, 0); +#endif + bus_space_write_1(iot, iohspc, SCMD, cmd); + + sc->sc_flags |= SPC_DOINGDMA; +} + +static +void spc_dio_dmadone(sc) + struct spc_softc *sc; +{ + struct spc_dio_softc *dsc = (struct spc_dio_softc *)sc; + bus_space_tag_t iot; + bus_space_handle_t ioh, iohsc; + int resid, trans; + u_int8_t cmd; + + iot = sc->sc_iot; + ioh = sc->sc_ioh; + iohsc = dsc->sc_iohsc; + + /* wait DMA complete */ + if ((bus_space_read_1(iot, ioh, SSTS) & SSTS_BUSY) != 0) { + int timeout = 1000; /* XXX how long? */ + while ((bus_space_read_1(iot, ioh, SSTS) & SSTS_BUSY) != 0) { + if (--timeout < 0) + printf("%s: DMA complete timeout\n", + sc->sc_dev.dv_xname); + DELAY(1); + } + } + + if ((dsc->sc_dflags & SCSI_HAVEDMA) != 0) { + dmafree(&dsc->sc_dq); + dsc->sc_dflags &= ~SCSI_HAVEDMA; + } + + cmd = bus_space_read_1(iot, iohsc, HPSCSI_CSR); + cmd &= ~(CSR_DE1|CSR_DE0); + bus_space_write_1(iot, iohsc, HPSCSI_CSR, cmd); + + resid = bus_space_read_1(iot, ioh, TCH) << 16 | + bus_space_read_1(iot, ioh, TCM) << 8 | + bus_space_read_1(iot, ioh, TCL); + trans = sc->sc_dleft - resid; + sc->sc_dp += trans; + sc->sc_dleft -= trans; + + sc->sc_flags &= ~SPC_DOINGDMA; +} + +static +void spc_dio_dmastop(arg) + void *arg; +{ + struct spc_dio_softc *dsc = (struct spc_dio_softc *)arg; + struct spc_softc *sc = &dsc->sc_spc; + u_int8_t cmd; + + /* XXX When is this function called? */ + cmd = bus_space_read_1(sc->sc_iot, dsc->sc_iohsc, HPSCSI_CSR); + cmd &= ~(CSR_DE1|CSR_DE0); + bus_space_write_1(sc->sc_iot, dsc->sc_iohsc, HPSCSI_CSR, cmd); + + dsc->sc_dflags &= ~SCSI_HAVEDMA; + sc->sc_flags &= ~SPC_DOINGDMA; +}