/* * vpo_probe() */ static int vpo_probe(device_t dev) { device_t ppbus = device_get_parent(dev); struct vpo_data *vpo; int error; vpo = DEVTOSOFTC(dev); vpo->vpo_dev = dev; /* check ZIP before ZIP+ or imm_probe() will send controls to * the printer or whatelse connected to the port */ ppb_lock(ppbus); if ((error = vpoio_probe(dev, &vpo->vpo_io)) == 0) { vpo->vpo_isplus = 0; device_set_desc(dev, "Iomega VPI0 Parallel to SCSI interface"); } else if ((error = imm_probe(dev, &vpo->vpo_io)) == 0) { vpo->vpo_isplus = 1; device_set_desc(dev, "Iomega Matchmaker Parallel to SCSI interface"); } else { ppb_unlock(ppbus); return (error); } ppb_unlock(ppbus); return (0); }
static int lpbb_callback(device_t dev, int index, caddr_t data) { device_t ppbus = device_get_parent(dev); int error = 0; int how; switch (index) { case IIC_REQUEST_BUS: /* request the ppbus */ how = *(int *)data; ppb_lock(ppbus); error = ppb_request_bus(ppbus, dev, how); ppb_unlock(ppbus); break; case IIC_RELEASE_BUS: /* release the ppbus */ ppb_lock(ppbus); error = ppb_release_bus(ppbus, dev); ppb_unlock(ppbus); break; default: error = EINVAL; } return (error); }
static int lpbb_detect(device_t dev) { device_t ppbus = device_get_parent(dev); ppb_lock(ppbus); if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) { ppb_unlock(ppbus); device_printf(dev, "can't allocate ppbus\n"); return (0); } lpbb_reset_bus(dev); if ((ppb_rstr(ppbus) & I2CKEY) || ((ppb_rstr(ppbus) & ALIM) != ALIM)) { ppb_release_bus(ppbus, dev); ppb_unlock(ppbus); return (0); } ppb_release_bus(ppbus, dev); ppb_unlock(ppbus); return (1); }
/* * vpo_attach() */ static int vpo_attach(device_t dev) { struct vpo_data *vpo = DEVTOSOFTC(dev); device_t ppbus = device_get_parent(dev); struct ppb_data *ppb = device_get_softc(ppbus); /* XXX: layering */ struct cam_devq *devq; int error; /* low level attachment */ if (vpo->vpo_isplus) { if ((error = imm_attach(&vpo->vpo_io))) return (error); } else { if ((error = vpoio_attach(&vpo->vpo_io))) return (error); } /* ** Now tell the generic SCSI layer ** about our bus. */ devq = cam_simq_alloc(/*maxopenings*/1); /* XXX What about low-level detach on error? */ if (devq == NULL) return (ENXIO); vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo, device_get_unit(dev), ppb->ppc_lock, /*untagged*/1, /*tagged*/0, devq); if (vpo->sim == NULL) { cam_simq_free(devq); return (ENXIO); } ppb_lock(ppbus); if (xpt_bus_register(vpo->sim, dev, /*bus*/0) != CAM_SUCCESS) { cam_sim_free(vpo->sim, /*free_devq*/TRUE); ppb_unlock(ppbus); return (ENXIO); } ppb_unlock(ppbus); return (0); }
/* * vpoio_attach() * * Low level attachment of vpo device * */ int vpoio_attach(struct vpoio_data *vpo) { DECLARE_NIBBLE_INBYTE_SUBMICROSEQ; device_t ppbus = device_get_parent(vpo->vpo_dev); int error = 0; vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc( sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT); if (!vpo->vpo_nibble_inbyte_msq) return (ENXIO); bcopy((void *)nibble_inbyte_submicroseq, (void *)vpo->vpo_nibble_inbyte_msq, sizeof(nibble_inbyte_submicroseq)); ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4, INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h, INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l, INB_NIBBLE_F, nibble_inbyte_hook, INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble); /* * Initialize mode dependent in/out microsequences */ ppb_lock(ppbus); if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT))) goto error; /* ppbus sets automatically the last mode entered during detection */ switch (vpo->vpo_mode_found) { case VP0_MODE_EPP: ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr_body); ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr_body); device_printf(vpo->vpo_dev, "EPP mode\n"); break; case VP0_MODE_PS2: ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq); ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq); device_printf(vpo->vpo_dev, "PS2 mode\n"); break; case VP0_MODE_NIBBLE: ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq); ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq); device_printf(vpo->vpo_dev, "NIBBLE mode\n"); break; default: panic("vpo: unknown mode %d", vpo->vpo_mode_found); } ppb_release_bus(ppbus, vpo->vpo_dev); error: ppb_unlock(ppbus); return (error); }
static int lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) { device_t ppbus = device_get_parent(dev); ppb_lock(ppbus); if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) { ppb_unlock(ppbus); device_printf(dev, "can't allocate ppbus\n"); return (0); } lpbb_reset_bus(dev); ppb_release_bus(ppbus, dev); ppb_unlock(ppbus); return (IIC_ENOADDR); }
static int lpbb_getsda(device_t dev) { device_t ppbus = device_get_parent(dev); int rval; ppb_lock(ppbus); rval = ((ppb_rstr(ppbus) & SDA_in) == SDA_in); ppb_unlock(ppbus); return (rval); }
static void lpbb_setscl(device_t dev, int val) { device_t ppbus = device_get_parent(dev); ppb_lock(ppbus); if (val == 0) ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) & ~SCL_out)); else ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) | SCL_out)); ppb_unlock(ppbus); }
static void lpbb_setsda(device_t dev, int val) { device_t ppbus = device_get_parent(dev); ppb_lock(ppbus); if (val == 0) ppb_wdtr(ppbus, (u_char)SDA_out); else ppb_wdtr(ppbus, (u_char)~SDA_out); ppb_unlock(ppbus); }