Index: dev/ic/mb89352.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/mb89352.c,v retrieving revision 1.21 diff -u -r1.21 mb89352.c --- dev/ic/mb89352.c 2003/07/27 03:51:28 1.21 +++ dev/ic/mb89352.c 2003/07/27 04:26:41 @@ -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 + #ifdef x68k /* XXX it seems x68k SPC SCSI hardware has some quirks */ #define NEED_DREQ_ON_HARDWARE_XFER #define NO_MANUAL_XFER @@ -550,8 +553,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; + } } } @@ -663,9 +677,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); @@ -1633,6 +1648,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. @@ -1939,6 +1965,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; @@ -1949,6 +1981,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/27 04:26:42 @@ -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 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/27 04:26:42 @@ -197,8 +197,7 @@ ite* at grf? # Internal Terminal Emulator -dca0 at dio? scode 9 flags 1 # DCA serial interfaces -dca* at dio? scode ? +com* at dio? scode ? # DCA serial interfaces dcm* at dio? scode ? flags 0xe # DCM 4- or 8-port serial interfaces @@ -218,11 +217,15 @@ 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 +spc* at dio? scode ? # HP 98265A SCSI +scsibus* at spc? -sd* at oscsi? target ? lun ? # SCSI disks -st* at oscsi? target ? lun ? # SCSI tapes -ac* at oscsi? target ? lun ? # SCSI changers +sd* at scsibus? target ? lun ? # SCSI disks +st* at scsibus? target ? lun ? # SCSI tapes +cd* at scsibus? target ? lun ? # SCSI CD-ROMs +ch* at scsibus? target ? lun ? # SCSI changer devices +ss* at scsibus? target ? lun ? # SCSI scanners +uk* at scsibus? target ? lun ? # unknown SCSI devices # # 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/27 04:26:42 @@ -121,9 +121,8 @@ attach topcat at dio with topcat_dio # DCA serial interface -device dca: tty -attach dca at dio -file arch/hp300/dev/dca.c dca needs-flag +attach com at dio with com_dio +file arch/hp300/dev/com_dio.c com_dio needs-flag # DCM serial interface device dcm: tty @@ -169,24 +168,13 @@ attach ppi at hpibbus 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 - -# 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 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 +# 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/conf/majors.hp300 =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/conf/majors.hp300,v retrieving revision 1.4 diff -u -r1.4 majors.hp300 --- arch/hp300/conf/majors.hp300 2003/04/25 21:10:53 1.4 +++ arch/hp300/conf/majors.hp300 2003/07/27 04:26:42 @@ -15,7 +15,7 @@ device-major rd char 9 block 2 rd device-major grf char 10 grf device-major ppi char 11 ppi -device-major dca char 12 dca +device-major com char 12 com device-major ite char 13 ite device-major hil char 14 device-major dcm char 15 dcm 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/27 04:26:42 @@ -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_oddbyte_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t)); +static void dio_bus_space_write_oddbyte_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t)); + +static void dio_bus_space_read_multi_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_1; + bst->bsw1 = dio_bus_space_write_oddbyte_1; + + bst->bsrm1 = dio_bus_space_read_multi_oddbyte_1; + bst->bswm1 = dio_bus_space_write_multi_oddbyte_1; + + bst->bsrr1 = dio_bus_space_read_region_oddbyte_1; + bst->bswr1 = dio_bus_space_write_region_oddbyte_1; + + bst->bssm1 = dio_bus_space_set_multi_oddbyte_1; + + bst->bssr1 = dio_bus_space_set_region_oddbyte_1; +} + +static u_int8_t +dio_bus_space_read_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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_oddbyte_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/27 04:26:43 @@ -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.16 diff -u -r1.16 intio.c --- arch/hp300/dev/intio.c 2003/07/05 16:21:17 1.16 +++ arch/hp300/dev/intio.c 2003/07/27 04:26:43 @@ -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.63 diff -u -r1.63 autoconf.c --- arch/hp300/hp300/autoconf.c 2003/07/27 04:38:06 1.63 +++ arch/hp300/hp300/autoconf.c 2003/07/27 04:43:08 @@ -108,7 +108,7 @@ #include "rbox.h" #include "rbox.h" #include "topcat.h" -#include "dca.h" +#include "com.h" #include "dcm.h" #include "apci.h" #include "ite.h" @@ -131,6 +131,10 @@ #include +#include +#include +#include + #include #include #include @@ -149,11 +153,12 @@ #include #include -#include +#if NCOM_DIO > 0 +#include +#endif /* should go away with a cleanup */ -extern int dcacnattach(bus_space_tag_t, bus_addr_t, int); extern int dcmcnattach(bus_space_tag_t, bus_addr_t, int); extern int apcicnattach(bus_space_tag_t, bus_addr_t, int); extern int dvboxcnattach(bus_space_tag_t, bus_addr_t, int); @@ -434,7 +439,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; @@ -450,10 +455,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; } @@ -472,7 +477,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; } @@ -602,23 +607,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) { @@ -685,9 +678,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++) { @@ -702,24 +697,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: @@ -800,15 +777,22 @@ 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 - if (!dio_scan(dcacnattach)) +#if NCOM_DIO > 0 + if (!dio_scan(com_dio_cnattach)) return; #endif #if NDCM > 0 @@ -822,19 +806,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 */ @@ -866,11 +850,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 */ } @@ -902,8 +886,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) @@ -914,7 +903,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.7 diff -u -r1.7 bus_space.c --- arch/hp300/hp300/bus_space.c 2003/07/19 16:02:06 1.7 +++ arch/hp300/hp300/bus_space.c 2003/07/27 04:26:44 @@ -68,7 +68,7 @@ vsize_t offset; 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. @@ -77,7 +77,7 @@ return (0); } - if (t != HP300_BUS_SPACE_DIO) + if (t->bustype != HP300_BUS_SPACE_DIO) panic("bus_space_map: bad space tag"); /* @@ -144,7 +144,7 @@ vaddr_t kva; vsize_t offset; - if (t == HP300_BUS_SPACE_INTIO) { + if (t->bustype == HP300_BUS_SPACE_INTIO) { /* * Intio space is direct-mapped in pmap_bootstrap(); nothing * to do @@ -152,7 +152,7 @@ return; } - if (t != HP300_BUS_SPACE_DIO) + if (t->bustype != HP300_BUS_SPACE_DIO) panic("bus_space_map: bad space tag"); kva = m68k_trunc_page(bsh); 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/27 04:26:45 @@ -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: arch/hp300/include/intr.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/include/intr.h,v retrieving revision 1.12 diff -u -r1.12 intr.h --- arch/hp300/include/intr.h 2001/12/08 04:09:19 1.12 +++ arch/hp300/include/intr.h 2003/07/27 04:26:45 @@ -109,6 +109,7 @@ #define splbio() _splraise(hp300_ipls[HP300_IPL_BIO]) #define splnet() _splraise(hp300_ipls[HP300_IPL_NET]) #define spltty() _splraise(hp300_ipls[HP300_IPL_TTY]) +#define splserial() spltty() #define splvm() _splraise(hp300_ipls[HP300_IPL_VM]) #define splclock() spl6() #define splstatclock() splclock() --- /dev/null 2003-07-27 12:39:50.000000000 +0900 +++ arch/hp300/dev/com_dio.c 2003-07-27 04:50:00.000000000 +0900 @@ -0,0 +1,216 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c) 1991 The Regents of the University of California. + * 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. 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. + * + * @(#)com.c 7.5 (Berkeley) 5/16/91 + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +struct com_dio_softc { + struct com_softc sc_com; /* real "com" softc */ + + /* DIO-specific goo. */ + struct bus_space_tag sc_tag; /* device specific bus space tag */ + void *sc_ih; /* interrupt handler */ +}; + +int com_dio_match(struct device *, struct cfdata *, void *); +void com_dio_attach(struct device *, struct device *, void *); + +CFATTACH_DECL(com_dio, sizeof(struct com_dio_softc), + com_dio_match, com_dio_attach, NULL, NULL); + +static int com_dio_speed = TTYDEF_SPEED; +static struct bus_space_tag comcntag; + +#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ + +int +com_dio_match(struct device *parent, struct cfdata *match, void *aux) +{ + struct dio_attach_args *da = aux; + + switch (da->da_id) { + case DIO_DEVICE_ID_DCA0: + case DIO_DEVICE_ID_DCA0REM: + case DIO_DEVICE_ID_DCA1: + case DIO_DEVICE_ID_DCA1REM: + return 1; + } + + return 0; +} + +void +com_dio_attach(struct device *parent, struct device *self, void *aux) +{ + struct com_dio_softc *dsc = (struct com_dio_softc *)self; + struct com_softc *sc = &dsc->sc_com; + bus_space_tag_t iot; + bus_space_handle_t iohdca, iohcom; + struct dio_attach_args *da = aux; + int isconsole; + + isconsole = com_is_console(&comcntag, da->da_addr + DCA_COM_OFFSET, + &iohcom); + + if (isconsole) { + iot = &comcntag; + bus_space_unmap(iot, iohcom, COM_NPORTS); + } else { + iot = &dsc->sc_tag; + memcpy(iot, da->da_bst, sizeof(struct bus_space_tag)); + dio_set_bus_space_oddbyte(iot); + } + + if (bus_space_map(iot, da->da_addr, DCA_SIZE, 0, &iohdca) || + bus_space_subregion(iot, iohdca, DCA_COM_OFFSET, + COM_NPORTS << 1, &iohcom)) { + printf(": can't map i/o space\n"); + return; + } + + if (!isconsole) { + bus_space_write_1(iot, iohdca, DCA_RESET, 0xff); + DELAY(1000); + } + + sc->sc_iot = iot; + sc->sc_ioh = iohcom; + sc->sc_iobase = da->da_addr + DCA_COM_OFFSET; + sc->sc_frequency = COM_DIO_FREQ; + + com_attach_subr(sc); + + dsc->sc_ih = dio_intr_establish(comintr, sc, da->da_ipl, + ((sc->sc_hwflags & COM_HW_FIFO) != 0) ? IPL_TTY : IPL_TTYNOBUF); + + /* Enable interrupts. */ + bus_space_write_1(iot, iohdca, DCA_IC, IC_IE); +} + +int +com_dio_cnattach(bus_space_tag_t bst, bus_addr_t addr, int scode) +{ + bus_space_tag_t iot = &comcntag; + bus_space_handle_t iohdca; + u_int8_t id; + + memcpy(iot, bst, sizeof(struct bus_space_tag)); + dio_set_bus_space_oddbyte(iot); + + if (bus_space_map(iot, addr, DCA_SIZE, 0, &iohdca)) + return 1; + bus_space_write_1(iot, iohdca, DCA_RESET, 0xff); + DELAY(100); + bus_space_write_1(iot, iohdca, DCA_IC, IC_IE); + + id = bus_space_read_1(iot, iohdca, DCA_ID); + bus_space_unmap(iot, iohdca, DCA_SIZE); + + switch (id) { +#ifdef CONSCODE + case DCAID0: + case DCAID1: +#endif + case DCAREMID0: + case DCAREMID1: + break; + default: + return 1; + } + + comcnattach(iot, addr + DCA_COM_OFFSET, com_dio_speed, COM_DIO_FREQ, + COM_TYPE_NORMAL, CONMODE); + + return 0; +} --- /dev/null 2003-07-27 12:39:50.000000000 +0900 +++ arch/hp300/dev/com_dioreg.h 2003-07-27 05:52:59.000000000 +0900 @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. 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. 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. + * + * @(#)dcareg.h 8.1 (Berkeley) 6/10/93 + */ + + +/* interface reset/id */ +#define DCA_ID 0x00 /* read */ +#define DCAID0 0x02 +#define DCAREMID0 0x82 +#define DCAID1 0x42 +#define DCAREMID1 0xC2 + +#define DCA_RESET 0x00 /* write */ + +/* interrupt control */ +#define DCA_IC 0x01 +#define DCAIPL(x) ((((x) >> 4) & 3) + 3) +#define IC_IR 0x40 +#define IC_IE 0x80 + +#define DCA_OCBRC 0x02 + +#define DCA_LCSM 0x03 + +#define DCA_SIZE 0x20 /* XXX */ +#define DCA_COM_OFFSET 0x10 /* XXX */ + +/* clock frequency */ +#define COM_DIO_FREQ 2457600 --- /dev/null 2003-07-27 12:39:50.000000000 +0900 +++ arch/hp300/dev/com_diovar.h 2003-07-27 04:50:00.000000000 +0900 @@ -0,0 +1,29 @@ +/* $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. + */ + +int com_dio_cnattach(bus_space_tag_t, bus_addr_t, int); --- /dev/null 2003-07-27 12:39:50.000000000 +0900 +++ arch/hp300/dev/hp98265reg.h 2003-07-27 04:50:06.000000000 +0900 @@ -0,0 +1,70 @@ +/* $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. 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-27 12:39:50.000000000 +0900 +++ arch/hp300/dev/spc.c 2003-07-27 04:52:37.000000000 +0900 @@ -0,0 +1,303 @@ +/* $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, da->da_addr, 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(": 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 interrupts. */ + 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) != 0) + /* 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); + 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; +}