Hi, i'm unsure about the accepted way of working around irregular registers, like would be needed with supporting Mentor OTG USB on both omap&sunxi on armv7. irregular as in _no_ correlation what so ever, so off*4 kind of solution does not apply. My question in particular is; is (ab)using bus_space for this accepted workaround?
NetBSD, where the driver got ported from, does have #ifdef MOTG_ALLWINNER which is obviously not possible, given GENERIC and its nature as true 'uni-mono-kernel'. i was actually a bit shocked when i figured how many arm kernel configs etc. they get to have maintenance-fun with if/when necessary :) reason why i think this is better than any other method to solve it in run-time rather than compile-time is, because it wouldn't affect other than the offender(=sunxi/Allwinner), no matter how ugly. shortened(actually +30cases in switch below) to show something like what i would propose: struct armv7_bus_space_tag sxiotg_bustag; void sxiotg_attach(struct device *parent, struct device *self, void *args) { /* ... */ sxiotg_bus_init(); sc->sc_motg.sc_bus.dmatag = &armv7_bus_dma_tag; sc->sc_motg.sc_iot = &sxiotg_bustag; /* ... */ printf(": OTG\n"); motg_init(&sc->sc_motg); } bus_size_t sxiotg_bs_hook(bus_size_t); u_int8_t sxiotg_bs_r_1(void *, bus_space_handle_t, bus_size_t); u_int16_t sxiotg_bs_r_2(void *, bus_space_handle_t, bus_size_t); void sxiotg_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t); void sxiotg_bs_w_2(void *, bus_space_handle_t, bus_size_t, u_int16_t); void sxiotg_bus_init(void) { memcpy(&sxiotg_bustag, &mainbus_bustag, sizeof(struct armv7_bus_space_tag)); sxiotg_bustag.bs_r_1 = sxiotg_bs_r_1; sxiotg_bustag.bs_w_1 = sxiotg_bs_w_1; sxiotg_bustag.bs_r_2 = sxiotg_bs_r_2; sxiotg_bustag.bs_w_2 = sxiotg_bs_w_2; /* tododiddone */ } bus_size_t sxiotg_bshook(bus_size_t off) { /* XXX separate hooks for 1&2 for less cases per switch?? */ switch (off) { case MUSB2_REG_FADDR: return MUSB2_REG_FADDR_AW; case MUSB2_REG_POWER: return MUSB2_REG_POWER_AW; case MUSB2_REG_DEVCTL: return MUSB2_REG_DEVCTL_AW; #if 0 /* * XXX duplicate case w/ _CONFDATA, but this is never hit on sunxi, * because we set sc_ep_fifosize, and so _FSIZE does not get read. */ case MUSB2_REG_FSIZE: return MUSB2_REG_FSIZE_AW; #endif case MUSB2_REG_EPFIFO(0): return MUSB2_REG_EPFIFO_AW(0); case MUSB2_REG_EPFIFO(1): return MUSB2_REG_EPFIFO_AW(1); case MUSB2_REG_EPFIFO(2): return MUSB2_REG_EPFIFO_AW(2); case MUSB2_REG_CONFDATA: return MUSB2_REG_CONFDATA_AW; case MUSB2_REG_TXFADDR(0): return MUSB2_REG_TXFADDR_AW; } return off; } u_int8_t sxiotg_bs_r_1(void *bst, bus_space_handle_t bsh, bus_size_t off) { return mainbus_bustag.bs_r_1(&mainbus_bustag, bsh, sxiotg_bshook(off)); } u_int16_t sxiotg_bs_r_2(void *bst, bus_space_handle_t bsh, bus_size_t off) { return mainbus_bustag.bs_r_2(&mainbus_bustag, bsh, sxiotg_bshook(off)); } void sxiotg_bs_w_1(void *bst, bus_space_handle_t bsh, bus_size_t off, u_int8_t val) { mainbus_bustag.bs_w_1(&mainbus_bustag, bsh, sxiotg_bshook(off), val); } void sxiotg_bs_w_2(void *bst, bus_space_handle_t bsh, bus_size_t off, u_int16_t val) { mainbus_bustag.bs_w_2(&mainbus_bustag, bsh, sxiotg_bshook(off), val); } -Artturi