/* * ppb_poll_bus() * * Polls the bus * * max is a delay in 10-milliseconds */ int ppb_poll_bus(device_t bus, int max, char mask, char status, int how) { struct ppb_data *ppb = DEVTOSOFTC(bus); int i, j, error; char r; ppb_assert_locked(bus); /* try at least up to 10ms */ for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) { for (i = 0; i < 10000; i++) { r = ppb_rstr(bus); DELAY(1); if ((r & mask) == status) return (0); } } if (!(how & PPB_POLL)) { for (i = 0; max == PPB_FOREVER || i < max-1; i++) { if ((ppb_rstr(bus) & mask) == status) return (0); /* wait 10 ms */ error = mtx_sleep((caddr_t)bus, ppb->ppc_lock, PPBPRI | (how == PPB_NOINTR ? 0 : PCATCH), "ppbpoll", hz/100); if (error != EWOULDBLOCK) return (error); } } return (EWOULDBLOCK); }
/* * ppb_ecp_sync() * * Wait for the ECP FIFO to be empty */ int ppb_ecp_sync(device_t bus) { ppb_assert_locked(bus); return (PPBUS_ECP_SYNC(device_get_parent(bus))); }
/* * ppb_reset_epp_timeout() * * Reset the EPP timeout bit in the status register */ int ppb_reset_epp_timeout(device_t bus) { ppb_assert_locked(bus); return(PPBUS_RESET_EPP(device_get_parent(bus))); }
/* * ppb_write() * * Write charaters to the port */ int ppb_write(device_t bus, char *buf, int len, int how) { ppb_assert_locked(bus); return (PPBUS_WRITE(device_get_parent(bus), buf, len, how)); }
/* * ppb_get_mode() * */ int ppb_get_mode(device_t bus) { struct ppb_data *ppb = DEVTOSOFTC(bus); /* XXX yet device mode = ppbus mode = chipset mode */ ppb_assert_locked(bus); return (ppb->mode); }
/* Reset bus by setting SDA first and then SCL. */ static void lpbb_reset_bus(device_t dev) { device_t ppbus = device_get_parent(dev); ppb_assert_locked(ppbus); ppb_wdtr(ppbus, (u_char)~SDA_out); ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus) | SCL_out)); }
/* * ppb_get_epp_protocol() * * Return the chipset EPP protocol */ int ppb_get_epp_protocol(device_t bus) { uintptr_t protocol; ppb_assert_locked(bus); BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO, &protocol); return (protocol); }
/* * ppb_set_mode() * * Set the operating mode of the chipset, return the previous mode */ int ppb_set_mode(device_t bus, int mode) { struct ppb_data *ppb = DEVTOSOFTC(bus); int old_mode = ppb_get_mode(bus); ppb_assert_locked(bus); if (PPBUS_SETMODE(device_get_parent(bus), mode)) return (-1); /* XXX yet device mode = ppbus mode = chipset mode */ ppb->mode = (mode & PPB_MASK); return (old_mode); }
/* * ppb_get_status() * * Read the status register and update the status info */ int ppb_get_status(device_t bus, struct ppb_status *status) { register char r; ppb_assert_locked(bus); r = status->status = ppb_rstr(bus); status->timeout = r & TIMEOUT; status->error = !(r & nFAULT); status->select = r & SELECT; status->paper_end = r & PERROR; status->ack = !(r & nACK); status->busy = !(r & nBUSY); return (0); }
static void vpo_action(struct cam_sim *sim, union ccb *ccb) { struct vpo_data *vpo = (struct vpo_data *)sim->softc; ppb_assert_locked(device_get_parent(vpo->vpo_dev)); switch (ccb->ccb_h.func_code) { case XPT_SCSI_IO: { struct ccb_scsiio *csio; csio = &ccb->csio; #ifdef VP0_DEBUG device_printf(vpo->vpo_dev, "XPT_SCSI_IO (0x%x) request\n", csio->cdb_io.cdb_bytes[0]); #endif vpo_intr(vpo, csio); xpt_done(ccb); break; } case XPT_CALC_GEOMETRY: { struct ccb_calc_geometry *ccg; ccg = &ccb->ccg; #ifdef VP0_DEBUG device_printf(vpo->vpo_dev, "XPT_CALC_GEOMETRY (bs=%d,vs=%jd,c=%d,h=%d,spt=%d) request\n", ccg->block_size, (intmax_t)ccg->volume_size, ccg->cylinders, ccg->heads, ccg->secs_per_track); #endif ccg->heads = 64; ccg->secs_per_track = 32; ccg->cylinders = ccg->volume_size / (ccg->heads * ccg->secs_per_track); ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; } case XPT_RESET_BUS: /* Reset the specified SCSI bus */ { #ifdef VP0_DEBUG device_printf(vpo->vpo_dev, "XPT_RESET_BUS request\n"); #endif if (vpo->vpo_isplus) { if (imm_reset_bus(&vpo->vpo_io)) { ccb->ccb_h.status = CAM_REQ_CMP_ERR; xpt_done(ccb); return; } } else { if (vpoio_reset_bus(&vpo->vpo_io)) { ccb->ccb_h.status = CAM_REQ_CMP_ERR; xpt_done(ccb); return; } } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; } case XPT_PATH_INQ: /* Path routing inquiry */ { struct ccb_pathinq *cpi = &ccb->cpi; #ifdef VP0_DEBUG device_printf(vpo->vpo_dev, "XPT_PATH_INQ request\n"); #endif cpi->version_num = 1; /* XXX??? */ cpi->hba_inquiry = 0; cpi->target_sprt = 0; cpi->hba_misc = 0; cpi->hba_eng_cnt = 0; cpi->max_target = 7; cpi->max_lun = 0; cpi->initiator_id = VP0_INITIATOR; cpi->bus_id = sim->bus_id; cpi->base_transfer_speed = 93; strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); strncpy(cpi->hba_vid, "Iomega", HBA_IDLEN); strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); cpi->unit_number = sim->unit_number; cpi->transport = XPORT_PPB; cpi->transport_version = 0; cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; } default: ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); break; } return; }