static void g_bde_orphan(struct g_consumer *cp) { struct g_geom *gp; struct g_provider *pp; struct g_bde_softc *sc; g_trace(G_T_TOPOLOGY, "g_bde_orphan(%p/%s)", cp, cp->provider->name); g_topology_assert(); gp = cp->geom; sc = gp->softc; gp->flags |= G_GEOM_WITHER; LIST_FOREACH(pp, &gp->provider, provider) g_orphan_provider(pp, ENXIO); bzero(sc, sizeof(struct g_bde_softc)); /* destroy evidence */ return; }
static void acd_read_toc(device_t dev) { struct ata_device *atadev = device_get_softc(dev); struct acd_softc *cdp = device_get_ivars(dev); struct g_provider *pp; u_int32_t sizes[2]; int8_t ccb[16]; int track, ntracks, len; atadev->flags &= ~ATA_D_MEDIA_CHANGED; bzero(&cdp->toc, sizeof(cdp->toc)); cdp->disk_size = -1; /* hack for GEOM SOS */ if (acd_test_ready(dev)) return; bzero(ccb, sizeof(ccb)); len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry); ccb[0] = ATAPI_READ_TOC; ccb[7] = len>>8; ccb[8] = len; if (ata_atapicmd(dev, ccb, (caddr_t)&cdp->toc, len, ATA_R_READ | ATA_R_QUIET, 30)) { bzero(&cdp->toc, sizeof(cdp->toc)); return; } ntracks = cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1; if (ntracks <= 0 || ntracks > MAXTRK) { bzero(&cdp->toc, sizeof(cdp->toc)); return; } len = sizeof(struct ioc_toc_header)+(ntracks+1)*sizeof(struct cd_toc_entry); bzero(ccb, sizeof(ccb)); ccb[0] = ATAPI_READ_TOC; ccb[7] = len>>8; ccb[8] = len; if (ata_atapicmd(dev, ccb, (caddr_t)&cdp->toc, len, ATA_R_READ | ATA_R_QUIET, 30)) { bzero(&cdp->toc, sizeof(cdp->toc)); return; } cdp->toc.hdr.len = ntohs(cdp->toc.hdr.len); cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352; acd_set_ioparm(dev); bzero(ccb, sizeof(ccb)); ccb[0] = ATAPI_READ_CAPACITY; if (ata_atapicmd(dev, ccb, (caddr_t)sizes, sizeof(sizes), ATA_R_READ | ATA_R_QUIET, 30)) { bzero(&cdp->toc, sizeof(cdp->toc)); return; } cdp->disk_size = ntohl(sizes[0]) + 1; for (track = 1; track <= ntracks; track ++) { if (cdp->pp[track] != NULL) continue; pp = g_new_providerf(cdp->gp, "acd%dt%02d", device_get_unit(dev),track); pp->index = track; cdp->pp[track] = pp; g_error_provider(pp, 0); } for (; track < MAXTRK; track ++) { if (cdp->pp[track] == NULL) continue; cdp->pp[track]->flags |= G_PF_WITHER; g_orphan_provider(cdp->pp[track], ENXIO); cdp->pp[track] = NULL; } #ifdef ACD_DEBUG if (cdp->disk_size && cdp->toc.hdr.ending_track) { device_printf(dev, "(%d sectors (%d bytes)), %d tracks ", cdp->disk_size, cdp->block_size, cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track+1); if (cdp->toc.tab[0].control & 4) printf("%dMB\n", cdp->disk_size * cdp->block_size / 1048576); else printf("%d:%d audio\n", cdp->disk_size / 75 / 60, cdp->disk_size / 75 % 60); } #endif }