static int ld_ataraid_biodisk(struct ld_ataraid_softc *sc, struct bioc_disk *bd) { struct ataraid_array_info *aai = sc->sc_aai; struct ataraid_disk_info *adi; struct ld_softc *ld = &sc->sc_ld; struct atabus_softc *atabus; struct wd_softc *wd; char model[81], serial[41], rev[17]; /* sanity check */ if (bd->bd_diskid > aai->aai_ndisks) return EINVAL; adi = &aai->aai_disks[bd->bd_diskid]; atabus = device_private(device_parent(adi->adi_dev)); wd = device_private(adi->adi_dev); /* fill in data for _this_ disk */ switch (adi->adi_status) { case ADI_S_ONLINE | ADI_S_ASSIGNED: bd->bd_status = BIOC_SDONLINE; break; case ADI_S_SPARE: bd->bd_status = BIOC_SDHOTSPARE; break; default: bd->bd_status = BIOC_SDOFFLINE; break; } bd->bd_channel = 0; bd->bd_target = atabus->sc_chan->ch_channel; bd->bd_lun = 0; bd->bd_size = (wd->sc_capacity * ld->sc_secsize) - aai->aai_reserved; strlcpy(bd->bd_procdev, device_xname(adi->adi_dev), sizeof(bd->bd_procdev)); scsipi_strvis(serial, sizeof(serial), wd->sc_params.atap_serial, sizeof(wd->sc_params.atap_serial)); scsipi_strvis(model, sizeof(model), wd->sc_params.atap_model, sizeof(wd->sc_params.atap_model)); scsipi_strvis(rev, sizeof(rev), wd->sc_params.atap_revision, sizeof(wd->sc_params.atap_revision)); snprintf(bd->bd_vendor, sizeof(bd->bd_vendor), "%s %s", model, rev); strlcpy(bd->bd_serial, serial, sizeof(bd->bd_serial)); return 0; }
Static void umass_atapi_probe_device(struct atapibus_softc *atapi, int target) { struct scsipi_channel *chan = atapi->sc_channel; struct scsipi_periph *periph; struct scsipibus_attach_args sa; char vendor[33], product[65], revision[17]; struct scsipi_inquiry_data inqbuf; DPRINTF(UDMASS_SCSI,("umass_atapi_probe_device: atapi=%p target=%d\n", atapi, target)); if (target != UMASS_ATAPI_DRIVE) /* only probe drive 0 */ return; KERNEL_LOCK(1, curlwp); /* skip if already attached */ if (scsipi_lookup_periph(chan, target, 0) != NULL) { KERNEL_UNLOCK_ONE(curlwp); return; } periph = scsipi_alloc_periph(M_NOWAIT); if (periph == NULL) { KERNEL_UNLOCK_ONE(curlwp); aprint_error_dev(atapi->sc_dev, "can't allocate link for drive %d\n", target); return; } DIF(UDMASS_UPPER, periph->periph_dbflags |= 1); /* XXX 1 */ periph->periph_channel = chan; periph->periph_switch = &atapi_probe_periphsw; periph->periph_target = target; periph->periph_quirks = chan->chan_defquirks; DPRINTF(UDMASS_SCSI, ("umass_atapi_probe_device: doing inquiry\n")); /* Now go ask the device all about itself. */ memset(&inqbuf, 0, sizeof(inqbuf)); if (scsipi_inquire(periph, &inqbuf, XS_CTL_DISCOVERY) != 0) { KERNEL_UNLOCK_ONE(curlwp); DPRINTF(UDMASS_SCSI, ("umass_atapi_probe_device: " "scsipi_inquire failed\n")); free(periph, M_DEVBUF); return; } scsipi_strvis(vendor, 33, inqbuf.vendor, 8); scsipi_strvis(product, 65, inqbuf.product, 16); scsipi_strvis(revision, 17, inqbuf.revision, 4); sa.sa_periph = periph; sa.sa_inqbuf.type = inqbuf.device; sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ? T_REMOV : T_FIXED; if (sa.sa_inqbuf.removable) periph->periph_flags |= PERIPH_REMOVABLE; sa.sa_inqbuf.vendor = vendor; sa.sa_inqbuf.product = product; sa.sa_inqbuf.revision = revision; sa.sa_inqptr = NULL; DPRINTF(UDMASS_SCSI, ("umass_atapi_probedev: doing atapi_probedev on " "'%s' '%s' '%s'\n", vendor, product, revision)); atapi_probe_device(atapi, target, periph, &sa); /* atapi_probe_device() frees the periph when there is no device.*/ KERNEL_UNLOCK_ONE(curlwp); }
static void wdc_atapi_probe_device(struct atapibus_softc *sc, int target) { struct scsipi_channel *chan = sc->sc_channel; struct scsipi_periph *periph; struct ataparams ids; struct ataparams *id = &ids; struct wdc_softc *wdc = device_private(chan->chan_adapter->adapt_dev); struct atac_softc *atac = &wdc->sc_atac; struct ata_channel *chp = atac->atac_channels[chan->chan_channel]; struct ata_drive_datas *drvp = &chp->ch_drive[target]; struct scsipibus_attach_args sa; char serial_number[21], model[41], firmware_revision[9]; int s; /* skip if already attached */ if (scsipi_lookup_periph(chan, target, 0) != NULL) return; /* if no ATAPI device detected at wdc attach time, skip */ if (drvp->drive_type != ATA_DRIVET_ATAPI) { ATADEBUG_PRINT(("wdc_atapi_probe_device: " "drive %d not present\n", target), DEBUG_PROBE); return; } if (wdc_atapi_get_params(chan, target, id) == 0) { #ifdef ATAPI_DEBUG_PROBE printf("%s drive %d: cmdsz 0x%x drqtype 0x%x\n", device_xname(sc->sc_dev), target, id->atap_config & ATAPI_CFG_CMD_MASK, id->atap_config & ATAPI_CFG_DRQ_MASK); #endif periph = scsipi_alloc_periph(M_NOWAIT); if (periph == NULL) { aprint_error_dev(sc->sc_dev, "unable to allocate periph for drive %d\n", target); return; } periph->periph_dev = NULL; periph->periph_channel = chan; periph->periph_switch = &atapi_probe_periphsw; periph->periph_target = target; periph->periph_lun = 0; periph->periph_quirks = PQUIRK_ONLYBIG; #ifdef SCSIPI_DEBUG if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_ATAPI && SCSIPI_DEBUG_TARGET == target) periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS; #endif periph->periph_type = ATAPI_CFG_TYPE(id->atap_config); if (id->atap_config & ATAPI_CFG_REMOV) periph->periph_flags |= PERIPH_REMOVABLE; if (periph->periph_type == T_SEQUENTIAL) { s = splbio(); drvp->drive_flags |= ATA_DRIVE_ATAPIDSCW; splx(s); } sa.sa_periph = periph; sa.sa_inqbuf.type = ATAPI_CFG_TYPE(id->atap_config); sa.sa_inqbuf.removable = id->atap_config & ATAPI_CFG_REMOV ? T_REMOV : T_FIXED; scsipi_strvis((u_char *)model, 40, id->atap_model, 40); scsipi_strvis((u_char *)serial_number, 20, id->atap_serial, 20); scsipi_strvis((u_char *)firmware_revision, 8, id->atap_revision, 8); sa.sa_inqbuf.vendor = model; sa.sa_inqbuf.product = serial_number; sa.sa_inqbuf.revision = firmware_revision; /* * Determine the operating mode capabilities of the device. */ if ((id->atap_config & ATAPI_CFG_CMD_MASK) == ATAPI_CFG_CMD_16) periph->periph_cap |= PERIPH_CAP_CMD16; /* XXX This is gross. */ periph->periph_cap |= (id->atap_config & ATAPI_CFG_DRQ_MASK); drvp->drv_softc = atapi_probe_device(sc, target, periph, &sa); if (drvp->drv_softc) ata_probe_caps(drvp); else { s = splbio(); drvp->drive_type = ATA_DRIVET_NONE; splx(s); } } else { s = splbio(); drvp->drive_type = ATA_DRIVET_NONE; splx(s); } }