static void isf_disk_insert(struct isf_softc *sc, off_t mediasize) { struct disk *disk; sc->isf_doomed = 0; sc->isf_erasing = 0; sc->isf_bstate = malloc(sizeof(*sc->isf_bstate) * (mediasize / ISF_ERASE_BLOCK), M_ISF, M_ZERO | M_WAITOK); kproc_create(&isf_task, sc, &sc->isf_proc, 0, 0, "isf"); disk = disk_alloc(); disk->d_drv1 = sc; disk->d_name = "isf"; disk->d_unit = sc->isf_unit; disk->d_strategy = isf_disk_strategy; disk->d_ioctl = isf_disk_ioctl; disk->d_sectorsize = ISF_SECTORSIZE; disk->d_mediasize = mediasize; disk->d_maxsize = ISF_SECTORSIZE; sc->isf_disk = disk; if (bootverbose) isf_dump_info(sc); disk_create(disk, DISK_VERSION); device_printf(sc->isf_dev, "%juM flash device\n", (uintmax_t)disk->d_mediasize / (1024 * 1024)); }
static int mfi_syspd_attach(device_t dev) { struct mfi_system_pd *sc; struct mfi_pd_info *pd_info; struct disk_info info; uint64_t sectors; uint32_t secsize; sc = device_get_softc(dev); pd_info = device_get_ivars(dev); sc->pd_dev = dev; sc->pd_id = pd_info->ref.v.device_id; sc->pd_unit = device_get_unit(dev); sc->pd_info = pd_info; sc->pd_controller = device_get_softc(device_get_parent(dev)); sc->pd_flags = MFI_DISK_FLAGS_SYSPD; sectors = pd_info->raw_size; secsize = MFI_SECTOR_LEN; lockmgr(&sc->pd_controller->mfi_io_lock, LK_EXCLUSIVE); TAILQ_INSERT_TAIL(&sc->pd_controller->mfi_syspd_tqh, sc, pd_link); lockmgr(&sc->pd_controller->mfi_io_lock, LK_RELEASE); device_printf(dev, "%juMB (%ju sectors) SYSPD volume\n", sectors / (1024 * 1024 / secsize), sectors); devstat_add_entry(&sc->pd_devstat, "mfisyspd", device_get_unit(dev), MFI_SECTOR_LEN, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER, DEVSTAT_PRIORITY_ARRAY); sc->pd_dev_t = disk_create(sc->pd_unit, &sc->pd_disk, &mfi_syspd_ops); sc->pd_dev_t->si_drv1 = sc; sc->pd_dev_t->si_iosize_max = sc->pd_controller->mfi_max_io * secsize; bzero(&info, sizeof(info)); info.d_media_blksize = secsize; /* mandatory */ info.d_media_blocks = sectors; if (info.d_media_blocks >= (1 * 1024 * 1024)) { info.d_nheads = 255; info.d_secpertrack = 63; } else { info.d_nheads = 64; info.d_secpertrack = 32; } disk_setdiskinfo(&sc->pd_disk, &info); return (0); }
static int opalflash_attach(device_t dev) { struct opalflash_softc *sc; phandle_t node; cell_t flash_blocksize, opal_id; uint32_t regs[2]; sc = device_get_softc(dev); sc->sc_dev = dev; node = ofw_bus_get_node(dev); OF_getencprop(node, "ibm,opal-id", &opal_id, sizeof(opal_id)); sc->sc_opal_id = opal_id; if (OF_getencprop(node, "ibm,flash-block-size", &flash_blocksize, sizeof(flash_blocksize)) < 0) { device_printf(dev, "Cannot determine flash block size.\n"); return (ENXIO); } if (!OF_hasprop(node, "no-erase")) sc->sc_erase = true; OPALFLASH_LOCK_INIT(sc); if (OF_getencprop(node, "reg", regs, sizeof(regs)) < 0) { device_printf(dev, "Unable to get flash size.\n"); return (ENXIO); } sc->sc_disk = disk_alloc(); sc->sc_disk->d_name = "opalflash"; sc->sc_disk->d_open = opalflash_open; sc->sc_disk->d_close = opalflash_close; sc->sc_disk->d_strategy = opalflash_strategy; sc->sc_disk->d_ioctl = opalflash_ioctl; sc->sc_disk->d_getattr = opalflash_getattr; sc->sc_disk->d_drv1 = sc; sc->sc_disk->d_maxsize = DFLTPHYS; sc->sc_disk->d_mediasize = regs[1]; sc->sc_disk->d_unit = device_get_unit(sc->sc_dev); sc->sc_disk->d_sectorsize = FLASH_BLOCKSIZE; sc->sc_disk->d_stripesize = flash_blocksize; sc->sc_disk->d_dump = NULL; disk_create(sc->sc_disk, DISK_VERSION); bioq_init(&sc->sc_bio_queue); kproc_create(&opalflash_task, sc, &sc->sc_p, 0, 0, "task: OPAL Flash"); return (0); }
static int cfi_disk_attach(device_t dev) { struct cfi_disk_softc *sc = device_get_softc(dev); sc->parent = device_get_softc(device_get_parent(dev)); /* validate interface width; assumed by other code */ if (sc->parent->sc_width != 1 && sc->parent->sc_width != 2 && sc->parent->sc_width != 4) return EINVAL; sc->disk = disk_alloc(); if (sc->disk == NULL) return ENOMEM; sc->disk->d_name = "cfid"; sc->disk->d_unit = device_get_unit(dev); sc->disk->d_open = cfi_disk_open; sc->disk->d_close = cfi_disk_close; sc->disk->d_strategy = cfi_disk_strategy; sc->disk->d_ioctl = cfi_disk_ioctl; sc->disk->d_dump = NULL; /* NB: no dumps */ sc->disk->d_getattr = cfi_disk_getattr; sc->disk->d_sectorsize = CFI_DISK_SECSIZE; sc->disk->d_mediasize = sc->parent->sc_size; sc->disk->d_maxsize = CFI_DISK_MAXIOSIZE; /* NB: use stripesize to hold the erase/region size */ if (sc->parent->sc_regions) { /* * Multiple regions, use the last one. This is a * total hack as it's (presently) used only by * geom_redboot to locate the FIS directory which * lies at the start of the last erase region. */ sc->disk->d_stripesize = sc->parent->sc_region[sc->parent->sc_regions-1].r_blksz; } else sc->disk->d_stripesize = sc->disk->d_mediasize; sc->disk->d_drv1 = sc; disk_create(sc->disk, DISK_VERSION); mtx_init(&sc->qlock, "CFID I/O lock", NULL, MTX_DEF); bioq_init(&sc->bioq); sc->tq = taskqueue_create("cfid_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->tq); taskqueue_start_threads(&sc->tq, 1, PI_DISK, "cfid taskq"); TASK_INIT(&sc->iotask, 0, cfi_io_proc, sc); return 0; }
static int ipsd_attach(device_t dev) { device_t adapter; ipsdisk_softc_t *dsc; struct disk_info info; u_int totalsectors; u_int nheads, nsectors; DEVICE_PRINTF(2, dev, "in attach\n"); dsc = (ipsdisk_softc_t *)device_get_softc(dev); bzero(dsc, sizeof(ipsdisk_softc_t)); adapter = device_get_parent(dev); dsc->dev = dev; dsc->sc = device_get_softc(adapter); dsc->unit = device_get_unit(dev); dsc->disk_number = (uintptr_t) device_get_ivars(dev); totalsectors = dsc->sc->drives[dsc->disk_number].sector_count; if ((totalsectors > 0x400000) && ((dsc->sc->adapter_info.miscflags & 0x8) == 0)) { nheads = IPS_NORM_HEADS; nsectors = IPS_NORM_SECTORS; } else { nheads = IPS_COMP_HEADS; nsectors = IPS_COMP_SECTORS; } devstat_add_entry(&dsc->stats, "ipsd", dsc->unit, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_SCSI, DEVSTAT_PRIORITY_DISK); dsc->ipsd_dev_t = disk_create(dsc->unit, &dsc->ipsd_disk, &ipsd_ops); dsc->ipsd_dev_t->si_drv1 = dsc; dsc->ipsd_dev_t->si_iosize_max = IPS_MAX_IO_SIZE; bzero(&info, sizeof(info)); info.d_media_blksize = IPS_BLKSIZE; /* mandatory */ info.d_media_blocks = totalsectors; info.d_type = DTYPE_ESDI; /* optional */ info.d_nheads = nheads; info.d_secpertrack = nsectors; info.d_ncylinders = totalsectors / nheads / nsectors; info.d_secpercyl = nsectors / nheads; disk_setdiskinfo(&dsc->ipsd_disk, &info); device_printf(dev, "Logical Drive (%dMB)\n", dsc->sc->drives[dsc->disk_number].sector_count >> 11); return 0; }
static int mfi_syspd_attach(device_t dev) { struct mfi_system_pd *sc; struct mfi_pd_info *pd_info; uint64_t sectors; uint32_t secsize; sc = device_get_softc(dev); pd_info = device_get_ivars(dev); sc->pd_dev = dev; sc->pd_id = pd_info->ref.v.device_id; sc->pd_unit = device_get_unit(dev); sc->pd_info = pd_info; sc->pd_controller = device_get_softc(device_get_parent(dev)); sc->pd_flags = 0; sectors = pd_info->raw_size; secsize = MFI_SECTOR_LEN; mtx_lock(&sc->pd_controller->mfi_io_lock); TAILQ_INSERT_TAIL(&sc->pd_controller->mfi_syspd_tqh, sc, pd_link); mtx_unlock(&sc->pd_controller->mfi_io_lock); device_printf(dev, "%juMB (%ju sectors) SYSPD volume\n", sectors / (1024 * 1024 / secsize), sectors); sc->pd_disk = disk_alloc(); sc->pd_disk->d_drv1 = sc; sc->pd_disk->d_maxsize = sc->pd_controller->mfi_max_io * secsize; sc->pd_disk->d_name = "mfisyspd"; sc->pd_disk->d_open = mfi_syspd_open; sc->pd_disk->d_close = mfi_syspd_close; sc->pd_disk->d_strategy = mfi_syspd_strategy; sc->pd_disk->d_dump = mfi_syspd_dump; sc->pd_disk->d_unit = sc->pd_unit; sc->pd_disk->d_sectorsize = secsize; sc->pd_disk->d_mediasize = sectors * secsize; if (sc->pd_disk->d_mediasize >= (1 * 1024 * 1024)) { sc->pd_disk->d_fwheads = 255; sc->pd_disk->d_fwsectors = 63; } else { sc->pd_disk->d_fwheads = 64; sc->pd_disk->d_fwsectors = 32; } disk_create(sc->pd_disk, DISK_VERSION); device_printf(dev, " SYSPD volume attached\n"); return (0); }
static int htif_blk_attach(device_t dev) { struct htif_blk_softc *sc; char prefix[] = " size="; char *str; long size; sc = device_get_softc(dev); sc->dev = dev; mtx_init(&sc->htif_io_mtx, device_get_nameunit(dev), "htif_blk", MTX_DEF); HTIF_BLK_LOCK_INIT(sc); str = strstr(htif_get_id(dev), prefix); size = strtol((str + 6), NULL, 10); if (size == 0) { return (ENXIO); } sc->index = htif_get_index(dev); if (sc->index < 0) return (EINVAL); htif_setup_intr(sc->index, htif_blk_intr, sc); sc->disk = disk_alloc(); sc->disk->d_drv1 = sc; sc->disk->d_maxsize = 4096; /* Max transfer */ sc->disk->d_name = "htif_blk"; sc->disk->d_open = htif_blk_open; sc->disk->d_close = htif_blk_close; sc->disk->d_strategy = htif_blk_strategy; sc->disk->d_unit = 0; sc->disk->d_sectorsize = SECTOR_SIZE; sc->disk->d_mediasize = size; disk_create(sc->disk, DISK_VERSION); bioq_init(&sc->bio_queue); sc->running = 1; kproc_create(&htif_blk_task, sc, &sc->p, 0, 0, "%s: transfer", device_get_nameunit(dev)); return (0); }
static int mambodisk_attach(device_t dev) { struct mambodisk_softc *sc; struct disk *d; intmax_t mb; char unit; sc = device_get_softc(dev); sc->dev = dev; MBODISK_LOCK_INIT(sc); d = sc->disk = disk_alloc(); d->d_open = mambodisk_open; d->d_close = mambodisk_close; d->d_strategy = mambodisk_strategy; d->d_name = "mambodisk"; d->d_drv1 = sc; d->d_maxsize = MAXPHYS; /* Maybe ask bridge? */ d->d_sectorsize = 512; sc->maxblocks = mambocall(MAMBO_DISK_INFO,MAMBO_INFO_BLKSZ,d->d_unit) / 512; d->d_unit = device_get_unit(dev); d->d_mediasize = mambocall(MAMBO_DISK_INFO,MAMBO_INFO_DEVSZ,d->d_unit) * 1024ULL; /* Mambo gives size in KB */ mb = d->d_mediasize >> 20; /* 1MiB == 1 << 20 */ unit = 'M'; if (mb >= 10240) { /* 1GiB = 1024 MiB */ unit = 'G'; mb /= 1024; } device_printf(dev, "%ju%cB, %d byte sectors\n", mb, unit, d->d_sectorsize); disk_create(d, DISK_VERSION); bioq_init(&sc->bio_queue); sc->running = 1; kproc_create(&mambodisk_task, sc, &sc->p, 0, 0, "task: mambo hd"); return (0); }
int disk_initialize(disk_t* disk){ int result=0; /* create new disk or startup existing disk */ if (use_existing_disk) { result = disk_startup(disk, disk_name); if (result == 0) { disk_size = disk->layout.size; disk_flags = disk->layout.flags; } else { disk_size = 0; disk_flags = DISK_READONLY; } } else { result = disk_create(disk, disk_name, disk_size, disk_flags); } return result; }
static int ipsd_attach(device_t dev) { device_t adapter; ipsdisk_softc_t *dsc; u_int totalsectors; DEVICE_PRINTF(2,dev, "in attach\n"); dsc = (ipsdisk_softc_t *)device_get_softc(dev); bzero(dsc, sizeof(ipsdisk_softc_t)); adapter = device_get_parent(dev); dsc->dev = dev; dsc->sc = device_get_softc(adapter); dsc->unit = device_get_unit(dev); dsc->disk_number = (uintptr_t) device_get_ivars(dev); dsc->ipsd_disk = disk_alloc(); dsc->ipsd_disk->d_drv1 = dsc; dsc->ipsd_disk->d_name = "ipsd"; dsc->ipsd_disk->d_maxsize = IPS_MAX_IO_SIZE; dsc->ipsd_disk->d_open = ipsd_open; dsc->ipsd_disk->d_close = ipsd_close; dsc->ipsd_disk->d_strategy = ipsd_strategy; dsc->ipsd_disk->d_dump = ipsd_dump; totalsectors = dsc->sc->drives[dsc->disk_number].sector_count; if ((totalsectors > 0x400000) && ((dsc->sc->adapter_info.miscflags & 0x8) == 0)) { dsc->ipsd_disk->d_fwheads = IPS_NORM_HEADS; dsc->ipsd_disk->d_fwsectors = IPS_NORM_SECTORS; } else { dsc->ipsd_disk->d_fwheads = IPS_COMP_HEADS; dsc->ipsd_disk->d_fwsectors = IPS_COMP_SECTORS; } dsc->ipsd_disk->d_sectorsize = IPS_BLKSIZE; dsc->ipsd_disk->d_mediasize = (off_t)totalsectors * IPS_BLKSIZE; dsc->ipsd_disk->d_unit = dsc->unit; dsc->ipsd_disk->d_flags = 0; disk_create(dsc->ipsd_disk, DISK_VERSION); device_printf(dev, "Logical Drive (%dMB)\n", dsc->sc->drives[dsc->disk_number].sector_count >> 11); return 0; }
int afdattach(struct ata_device *atadev) { struct afd_softc *fdp; dev_t dev; fdp = malloc(sizeof(struct afd_softc), M_AFD, M_NOWAIT | M_ZERO); if (!fdp) { ata_prtdev(atadev, "out of memory\n"); return 0; } fdp->device = atadev; fdp->lun = ata_get_lun(&afd_lun_map); ata_set_name(atadev, "afd", fdp->lun); bufq_init(&fdp->queue); if (afd_sense(fdp)) { free(fdp, M_AFD); return 0; } devstat_add_entry(&fdp->stats, "afd", fdp->lun, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_WFD); dev = disk_create(fdp->lun, &fdp->disk, 0, &afd_cdevsw, &afddisk_cdevsw); dev->si_drv1 = fdp; fdp->dev = dev; if (!strncmp(atadev->param->model, "IOMEGA ZIP", 10) || !strncmp(atadev->param->model, "IOMEGA Clik!", 12)) fdp->dev->si_iosize_max = 64 * DEV_BSIZE; else fdp->dev->si_iosize_max = 252 * DEV_BSIZE; afd_describe(fdp); atadev->flags |= ATA_D_MEDIA_CHANGED; atadev->driver = fdp; return 1; }
static int afd_attach(device_t dev) { struct ata_channel *ch = device_get_softc(device_get_parent(dev)); struct ata_device *atadev = device_get_softc(dev); struct afd_softc *fdp; if (!(fdp = malloc(sizeof(struct afd_softc), M_AFD, M_NOWAIT | M_ZERO))) { device_printf(dev, "out of memory\n"); return ENOMEM; } device_set_ivars(dev, fdp); ata_setmode(dev); if (afd_sense(dev)) { device_set_ivars(dev, NULL); free(fdp, M_AFD); return ENXIO; } atadev->flags |= ATA_D_MEDIA_CHANGED; /* announce we are here */ afd_describe(dev); /* create the disk device */ fdp->disk = disk_alloc(); fdp->disk->d_open = afd_open; fdp->disk->d_close = afd_close; fdp->disk->d_strategy = afd_strategy; fdp->disk->d_ioctl = afd_ioctl; fdp->disk->d_name = "afd"; fdp->disk->d_drv1 = dev; fdp->disk->d_maxsize = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; fdp->disk->d_unit = device_get_unit(dev); disk_create(fdp->disk, DISK_VERSION); return 0; }
struct qid object_create(Worker *worker, u64 oid, u32 mode, u32 ctime, char *uid, char *gid, char *extension) { Transaction *trans = trans_new(storage_servers[0], NULL, message_new()); struct Rscreate *res; int len; /* create it in the cache */ if (objectroot != NULL) { len = disk_create(worker, oid, mode, ctime, uid, gid, extension); assert(len >= 0); object_cache_validate(oid); } /* create it on the storage servers */ trans->out->tag = ALLOCTAG; trans->out->id = TSCREATE; set_tscreate(trans->out, oid, mode, ctime, uid, gid, extension); send_request_to_all(trans, NULL, NULL); res = &trans->in->msg.rscreate; return res->qid; }
static int afd_attach(device_t dev) { struct ata_channel *ch = device_get_softc(device_get_parent(dev)); struct ata_device *atadev = device_get_softc(dev); struct afd_softc *fdp; cdev_t cdev; fdp = kmalloc(sizeof(struct afd_softc), M_AFD, M_WAITOK | M_ZERO); device_set_ivars(dev, fdp); ATA_SETMODE(device_get_parent(dev), dev); if (afd_sense(dev)) { device_set_ivars(dev, NULL); kfree(fdp, M_AFD); return ENXIO; } atadev->flags |= ATA_D_MEDIA_CHANGED; /* create the disk device */ devstat_add_entry(&fdp->stats, "afd", device_get_unit(dev), DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_WFD); cdev = disk_create(device_get_unit(dev), &fdp->disk, &afd_ops); disk_setdisktype(&fdp->disk, "floppy"); cdev->si_drv1 = dev; if (ch->dma) cdev->si_iosize_max = ch->dma->max_iosize; else cdev->si_iosize_max = min(MAXPHYS,64*1024); fdp->cdev = cdev; /* announce we are here */ afd_describe(dev); return 0; }
static int pst_attach(device_t dev) { struct pst_softc *psc = device_get_softc(dev); struct i2o_get_param_reply *reply; struct i2o_device_identity *ident; int lun = device_get_unit(dev); int8_t name [32]; if (!(reply = iop_get_util_params(psc->iop, psc->lct->local_tid, I2O_PARAMS_OPERATION_FIELD_GET, I2O_BSA_DEVICE_INFO_GROUP_NO))) return ENODEV; if (!(psc->info = (struct i2o_bsa_device *) malloc(sizeof(struct i2o_bsa_device), M_PSTRAID, M_NOWAIT))) { contigfree(reply, PAGE_SIZE, M_PSTIOP); return ENOMEM; } bcopy(reply->result, psc->info, sizeof(struct i2o_bsa_device)); contigfree(reply, PAGE_SIZE, M_PSTIOP); if (!(reply = iop_get_util_params(psc->iop, psc->lct->local_tid, I2O_PARAMS_OPERATION_FIELD_GET, I2O_UTIL_DEVICE_IDENTITY_GROUP_NO))) return ENODEV; ident = (struct i2o_device_identity *)reply->result; #ifdef PSTDEBUG printf("pst: vendor=<%.16s> product=<%.16s>\n", ident->vendor, ident->product); printf("pst: description=<%.16s> revision=<%.8s>\n", ident->description, ident->revision); printf("pst: capacity=%lld blocksize=%d\n", psc->info->capacity, psc->info->block_size); #endif bpack(ident->vendor, ident->vendor, 16); bpack(ident->product, ident->product, 16); sprintf(name, "%s %s", ident->vendor, ident->product); contigfree(reply, PAGE_SIZE, M_PSTIOP); bioq_init(&psc->queue); psc->disk = disk_alloc(); psc->disk->d_name = "pst"; psc->disk->d_strategy = pststrategy; psc->disk->d_maxsize = 64 * 1024; /*I2O_SGL_MAX_SEGS * PAGE_SIZE;*/ psc->disk->d_drv1 = psc; psc->disk->d_unit = lun; psc->disk->d_sectorsize = psc->info->block_size; psc->disk->d_mediasize = psc->info->capacity; psc->disk->d_fwsectors = 63; psc->disk->d_fwheads = 255; disk_create(psc->disk, DISK_VERSION); printf("pst%d: %lluMB <%.40s> [%lld/%d/%d] on %.16s\n", lun, (unsigned long long)psc->info->capacity / (1024 * 1024), name, psc->info->capacity/(512*255*63), 255, 63, device_get_nameunit(psc->iop->dev)); EVENTHANDLER_REGISTER(shutdown_post_sync, pst_shutdown, dev, SHUTDOWN_PRI_FIRST); return 0; }
static int mfi_disk_attach(device_t dev) { struct mfi_disk *sc; struct mfi_ld_info *ld_info; struct disk_info info; uint64_t sectors; uint32_t secsize; char *state; sc = device_get_softc(dev); ld_info = device_get_ivars(dev); sc->ld_dev = dev; sc->ld_id = ld_info->ld_config.properties.ld.v.target_id; sc->ld_unit = device_get_unit(dev); sc->ld_info = ld_info; sc->ld_controller = device_get_softc(device_get_parent(dev)); sc->ld_flags = 0; sectors = ld_info->size; secsize = MFI_SECTOR_LEN; lockmgr(&sc->ld_controller->mfi_io_lock, LK_EXCLUSIVE); TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, sc, ld_link); lockmgr(&sc->ld_controller->mfi_io_lock, LK_RELEASE); switch (ld_info->ld_config.params.state) { case MFI_LD_STATE_OFFLINE: state = "offline"; break; case MFI_LD_STATE_PARTIALLY_DEGRADED: state = "partially degraded"; break; case MFI_LD_STATE_DEGRADED: state = "degraded"; break; case MFI_LD_STATE_OPTIMAL: state = "optimal"; break; default: state = "unknown"; break; } device_printf(dev, "%juMB (%ju sectors) RAID volume '%s' is %s\n", sectors / (1024 * 1024 / secsize), sectors, ld_info->ld_config.properties.name, state); devstat_add_entry(&sc->ld_devstat, "mfid", device_get_unit(dev), MFI_SECTOR_LEN, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER, DEVSTAT_PRIORITY_ARRAY); sc->ld_dev_t = disk_create(sc->ld_unit, &sc->ld_disk, &mfi_disk_ops); sc->ld_dev_t->si_drv1 = sc; sc->ld_dev_t->si_iosize_max = min(sc->ld_controller->mfi_max_io * secsize, (sc->ld_controller->mfi_max_sge - 1) * PAGE_SIZE); bzero(&info, sizeof(info)); info.d_media_blksize = secsize; /* mandatory */ info.d_media_blocks = sectors; if (info.d_media_blocks >= (1 * 1024 * 1024)) { info.d_nheads = 255; info.d_secpertrack = 63; } else { info.d_nheads = 64; info.d_secpertrack = 32; } disk_setdiskinfo(&sc->ld_disk, &info); return (0); }
static void * nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) { uint8_t descr[NVME_MODEL_NUMBER_LENGTH+1]; struct nvd_disk *ndisk; struct disk *disk; struct nvd_controller *ctrlr = ctrlr_arg; ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK); disk = disk_alloc(); disk->d_strategy = nvd_strategy; disk->d_ioctl = nvd_ioctl; disk->d_name = NVD_STR; disk->d_drv1 = ndisk; disk->d_maxsize = nvme_ns_get_max_io_xfer_size(ns); disk->d_sectorsize = nvme_ns_get_sector_size(ns); disk->d_mediasize = (off_t)nvme_ns_get_size(ns); if (TAILQ_EMPTY(&disk_head)) disk->d_unit = 0; else disk->d_unit = TAILQ_LAST(&disk_head, disk_list)->disk->d_unit + 1; disk->d_flags = 0; if (nvme_ns_get_flags(ns) & NVME_NS_DEALLOCATE_SUPPORTED) disk->d_flags |= DISKFLAG_CANDELETE; if (nvme_ns_get_flags(ns) & NVME_NS_FLUSH_SUPPORTED) disk->d_flags |= DISKFLAG_CANFLUSHCACHE; /* ifdef used here to ease porting to stable branches at a later point. */ #ifdef DISKFLAG_UNMAPPED_BIO disk->d_flags |= DISKFLAG_UNMAPPED_BIO; #endif /* * d_ident and d_descr are both far bigger than the length of either * the serial or model number strings. */ nvme_strvis(disk->d_ident, nvme_ns_get_serial_number(ns), sizeof(disk->d_ident), NVME_SERIAL_NUMBER_LENGTH); nvme_strvis(descr, nvme_ns_get_model_number(ns), sizeof(descr), NVME_MODEL_NUMBER_LENGTH); #if __FreeBSD_version >= 900034 strlcpy(disk->d_descr, descr, sizeof(descr)); #endif ndisk->ns = ns; ndisk->disk = disk; ndisk->cur_depth = 0; mtx_init(&ndisk->bioqlock, "NVD bioq lock", NULL, MTX_DEF); bioq_init(&ndisk->bioq); TASK_INIT(&ndisk->bioqtask, 0, nvd_bioq_process, ndisk); ndisk->tq = taskqueue_create("nvd_taskq", M_WAITOK, taskqueue_thread_enqueue, &ndisk->tq); taskqueue_start_threads(&ndisk->tq, 1, PI_DISK, "nvd taskq"); TAILQ_INSERT_TAIL(&disk_head, ndisk, global_tailq); TAILQ_INSERT_TAIL(&ctrlr->disk_head, ndisk, ctrlr_tailq); disk_create(disk, DISK_VERSION); printf(NVD_STR"%u: <%s> NVMe namespace\n", disk->d_unit, descr); printf(NVD_STR"%u: %juMB (%ju %u byte sectors)\n", disk->d_unit, (uintmax_t)disk->d_mediasize / (1024*1024), (uintmax_t)disk->d_mediasize / disk->d_sectorsize, disk->d_sectorsize); return (NULL); }
int create_geom_disk(struct nand_chip *chip) { struct disk *ndisk, *rdisk; /* Create the disk device */ ndisk = disk_alloc(); ndisk->d_strategy = nand_strategy; ndisk->d_ioctl = nand_ioctl; ndisk->d_getattr = nand_getattr; ndisk->d_name = "gnand"; ndisk->d_drv1 = chip; ndisk->d_maxsize = chip->chip_geom.block_size; ndisk->d_sectorsize = chip->chip_geom.page_size; ndisk->d_mediasize = chip->chip_geom.chip_size; ndisk->d_unit = chip->num + 10 * device_get_unit(device_get_parent(chip->dev)); /* * When using BBT, make two last blocks of device unavailable * to user (because those are used to store BBT table). */ if (chip->bbt != NULL) ndisk->d_mediasize -= (2 * chip->chip_geom.block_size); ndisk->d_flags = DISKFLAG_CANDELETE; snprintf(ndisk->d_ident, sizeof(ndisk->d_ident), "nand: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id); ndisk->d_rotation_rate = DISK_RR_NON_ROTATING; disk_create(ndisk, DISK_VERSION); /* Create the RAW disk device */ rdisk = disk_alloc(); rdisk->d_strategy = nand_strategy_raw; rdisk->d_ioctl = nand_ioctl; rdisk->d_getattr = nand_getattr; rdisk->d_name = "gnand.raw"; rdisk->d_drv1 = chip; rdisk->d_maxsize = chip->chip_geom.block_size; rdisk->d_sectorsize = chip->chip_geom.page_size; rdisk->d_mediasize = chip->chip_geom.chip_size; rdisk->d_unit = chip->num + 10 * device_get_unit(device_get_parent(chip->dev)); rdisk->d_flags = DISKFLAG_CANDELETE; snprintf(rdisk->d_ident, sizeof(rdisk->d_ident), "nand_raw: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id); rdisk->d_rotation_rate = DISK_RR_NON_ROTATING; disk_create(rdisk, DISK_VERSION); chip->ndisk = ndisk; chip->rdisk = rdisk; mtx_init(&chip->qlock, "NAND I/O lock", NULL, MTX_DEF); bioq_init(&chip->bioq); TASK_INIT(&chip->iotask, 0, nand_io_proc, chip); chip->tq = taskqueue_create("nand_taskq", M_WAITOK, taskqueue_thread_enqueue, &chip->tq); taskqueue_start_threads(&chip->tq, 1, PI_DISK, "nand taskq"); if (bootverbose) device_printf(chip->dev, "Created gnand%d for chip [0x%0x, " "0x%0x]\n", ndisk->d_unit, chip->id.man_id, chip->id.dev_id); return (0); }
void object_fetch(Worker *worker, u64 oid, struct p9stat *info) { int res; u32 packetsize; u32 packetcount; u64 offset; int i; int start; u32 time = now(); List **queues; struct object_fetch_env env; if (objectroot == NULL || object_cache_isvalid(oid)) return; /* delete any existing entry in the cache */ res = disk_delete(worker, oid); assert(res >= 0 || -res == ENOENT); /* create the file */ disk_create(worker, oid, info->mode, info->mtime, info->uid, info->gid, info->extension); /* empty file? */ if (info->length == 0 || !emptystring(info->extension)) { int res = disk_wstat(worker, oid, info); assert(res == 0); return; } /* stripe the reads across the storage servers */ queues = GC_MALLOC(sizeof(List *) * storage_server_count); assert(queues != NULL); queues[0] = NULL; packetsize = (storage_servers[0]->maxSize / BLOCK_SIZE) * BLOCK_SIZE; for (i = 1; i < storage_server_count; i++) { int size = (storage_servers[i]->maxSize / BLOCK_SIZE) * BLOCK_SIZE; packetsize = min(packetsize, size); queues[i] = NULL; } packetcount = (info->length + (packetsize - 1)) / packetsize; i = 0; offset = 0; start = randInt(storage_server_count); /* create read requests in contiguous chunks for each server */ while (offset < info->length) { u64 size = info->length - offset; if (size > packetsize) size = packetsize; Transaction *trans = trans_new( storage_servers[(i + start) % storage_server_count], NULL, message_new()); trans->out->tag = ALLOCTAG; trans->out->id = TSREAD; set_tsread(trans->out, oid, time, offset, (u32) size); queues[i] = cons(trans, queues[i]); offset += size; /* time to switch to next server? */ if (offset * storage_server_count > info->length * (i + 1)) i++; } /* put the requests in sequential order */ for (i = 0; i < storage_server_count; i++) queues[i] = reverse(queues[i]); env.file = disk_get_openfile(worker, oid); assert(env.file != NULL); env.wait = NULL; if (ftruncate(env.file->fd, info->length) < 0) assert(0); send_requests_streamed(queues, storage_server_count, (void (*)(void *, Transaction *)) object_fetch_iter, &env); if (disk_wstat(worker, oid, info) != 0) assert(0); object_cache_validate(oid); }
static int ad_attach(device_t dev) { struct ata_channel *ch = device_get_softc(device_get_parent(dev)); struct ata_device *atadev = device_get_softc(dev); struct ad_softc *adp; device_t parent; /* check that we have a virgin disk to attach */ if (device_get_ivars(dev)) return EEXIST; if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT | M_ZERO))) { device_printf(dev, "out of memory\n"); return ENOMEM; } device_set_ivars(dev, adp); /* get device geometry into internal structs */ if (ad_get_geometry(dev)) return ENXIO; /* set the max size if configured */ if (ata_setmax) ad_set_geometry(dev); /* init device parameters */ ad_init(dev); /* announce we are here */ ad_describe(dev); /* create the disk device */ adp->disk = disk_alloc(); adp->disk->d_strategy = ad_strategy; adp->disk->d_ioctl = ad_ioctl; adp->disk->d_dump = ad_dump; adp->disk->d_name = "ad"; adp->disk->d_drv1 = dev; adp->disk->d_maxsize = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) adp->disk->d_maxsize = min(adp->disk->d_maxsize, 65536 * DEV_BSIZE); else /* 28bit ATA command limit */ adp->disk->d_maxsize = min(adp->disk->d_maxsize, 256 * DEV_BSIZE); adp->disk->d_sectorsize = DEV_BSIZE; adp->disk->d_mediasize = DEV_BSIZE * (off_t)adp->total_secs; adp->disk->d_fwsectors = adp->sectors; adp->disk->d_fwheads = adp->heads; adp->disk->d_unit = device_get_unit(dev); if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) adp->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; if ((atadev->param.support.command2 & ATA_SUPPORT_CFA) || atadev->param.config == ATA_PROTO_CFA) adp->disk->d_flags |= DISKFLAG_CANDELETE; strlcpy(adp->disk->d_ident, atadev->param.serial, sizeof(adp->disk->d_ident)); strlcpy(adp->disk->d_descr, atadev->param.model, sizeof(adp->disk->d_descr)); parent = device_get_parent(ch->dev); if (parent != NULL && device_get_parent(parent) != NULL && (device_get_devclass(parent) == devclass_find("atapci") || device_get_devclass(device_get_parent(parent)) == devclass_find("pci"))) { adp->disk->d_hba_vendor = pci_get_vendor(parent); adp->disk->d_hba_device = pci_get_device(parent); adp->disk->d_hba_subvendor = pci_get_subvendor(parent); adp->disk->d_hba_subdevice = pci_get_subdevice(parent); } ata_disk_firmware_geom_adjust(adp->disk); disk_create(adp->disk, DISK_VERSION); device_add_child(dev, "subdisk", device_get_unit(dev)); bus_generic_attach(dev); callout_init(&atadev->spindown_timer, 1); return 0; }
static int mlxd_attach(device_t dev) { struct mlxd_softc *sc = (struct mlxd_softc *)device_get_softc(dev); device_t parent; char *state; int s1, s2; debug_called(1); parent = device_get_parent(dev); sc->mlxd_controller = (struct mlx_softc *)device_get_softc(parent); sc->mlxd_unit = device_get_unit(dev); sc->mlxd_drive = device_get_ivars(dev); sc->mlxd_dev = dev; switch(sc->mlxd_drive->ms_state) { case MLX_SYSD_ONLINE: state = "online"; break; case MLX_SYSD_CRITICAL: state = "critical"; break; case MLX_SYSD_OFFLINE: state = "offline"; break; default: state = "unknown state"; } device_printf(dev, "%uMB (%u sectors) RAID %d (%s)\n", sc->mlxd_drive->ms_size / ((1024 * 1024) / MLX_BLKSIZE), sc->mlxd_drive->ms_size, sc->mlxd_drive->ms_raidlevel, state); sc->mlxd_disk = disk_alloc(); sc->mlxd_disk->d_open = mlxd_open; sc->mlxd_disk->d_close = mlxd_close; sc->mlxd_disk->d_ioctl = mlxd_ioctl; sc->mlxd_disk->d_strategy = mlxd_strategy; sc->mlxd_disk->d_name = "mlxd"; sc->mlxd_disk->d_unit = sc->mlxd_unit; sc->mlxd_disk->d_drv1 = sc; sc->mlxd_disk->d_sectorsize = MLX_BLKSIZE; sc->mlxd_disk->d_mediasize = MLX_BLKSIZE * (off_t)sc->mlxd_drive->ms_size; sc->mlxd_disk->d_fwsectors = sc->mlxd_drive->ms_sectors; sc->mlxd_disk->d_fwheads = sc->mlxd_drive->ms_heads; /* * Set maximum I/O size to the lesser of the recommended maximum and the practical * maximum except on v2 cards where the maximum is set to 8 pages. */ if (sc->mlxd_controller->mlx_iftype == MLX_IFTYPE_2) sc->mlxd_disk->d_maxsize = 8 * MLX_PAGE_SIZE; else { s1 = sc->mlxd_controller->mlx_enq2->me_maxblk * MLX_BLKSIZE; s2 = (sc->mlxd_controller->mlx_enq2->me_max_sg - 1) * MLX_PAGE_SIZE; sc->mlxd_disk->d_maxsize = imin(s1, s2); } disk_create(sc->mlxd_disk, DISK_VERSION); return (0); }
static int ad_attach(device_t dev) { struct ata_channel *ch = device_get_softc(device_get_parent(dev)); struct ata_device *atadev = device_get_softc(dev); struct disk_info info; struct ad_softc *adp; cdev_t cdev; u_int32_t lbasize; u_int64_t lbasize48; /* check that we have a virgin disk to attach */ if (device_get_ivars(dev)) return EEXIST; adp = kmalloc(sizeof(struct ad_softc), M_AD, M_INTWAIT | M_ZERO); device_set_ivars(dev, adp); if ((atadev->param.atavalid & ATA_FLAG_54_58) && atadev->param.current_heads && atadev->param.current_sectors) { adp->heads = atadev->param.current_heads; adp->sectors = atadev->param.current_sectors; adp->total_secs = (u_int32_t)atadev->param.current_size_1 | ((u_int32_t)atadev->param.current_size_2 << 16); } else { adp->heads = atadev->param.heads; adp->sectors = atadev->param.sectors; adp->total_secs = atadev->param.cylinders * adp->heads * adp->sectors; } lbasize = (u_int32_t)atadev->param.lba_size_1 | ((u_int32_t)atadev->param.lba_size_2 << 16); /* does this device need oldstyle CHS addressing */ if (!ad_version(atadev->param.version_major) || !lbasize) atadev->flags |= ATA_D_USE_CHS; /* use the 28bit LBA size if valid or bigger than the CHS mapping */ if (atadev->param.cylinders == 16383 || adp->total_secs < lbasize) adp->total_secs = lbasize; /* use the 48bit LBA size if valid */ lbasize48 = ((u_int64_t)atadev->param.lba_size48_1) | ((u_int64_t)atadev->param.lba_size48_2 << 16) | ((u_int64_t)atadev->param.lba_size48_3 << 32) | ((u_int64_t)atadev->param.lba_size48_4 << 48); if ((atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) && lbasize48 > ATA_MAX_28BIT_LBA) adp->total_secs = lbasize48; /* init device parameters */ ad_init(dev); /* create the disk device */ /* XXX TGEN Maybe use DEVSTAT_ALL_SUPPORTED, DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX. */ devstat_add_entry(&adp->stats, "ad", device_get_unit(dev), DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_DISK); cdev = disk_create(device_get_unit(dev), &adp->disk, &ad_ops); cdev->si_drv1 = dev; if (ch->dma) cdev->si_iosize_max = ch->dma->max_iosize; else cdev->si_iosize_max = DFLTPHYS; adp->cdev = cdev; bzero(&info, sizeof(info)); info.d_media_blksize = DEV_BSIZE; /* mandatory */ info.d_media_blocks = adp->total_secs; info.d_secpertrack = adp->sectors; /* optional */ info.d_nheads = adp->heads; info.d_ncylinders = adp->total_secs/(adp->heads*adp->sectors); info.d_secpercyl = adp->sectors * adp->heads; info.d_serialno = atadev->param.serial; device_add_child(dev, "subdisk", device_get_unit(dev)); bus_generic_attach(dev); /* announce we are here */ ad_describe(dev); disk_setdiskinfo(&adp->disk, &info); return 0; }
static int mfi_disk_attach(device_t dev) { struct mfi_disk *sc; struct mfi_ld_info *ld_info; uint64_t sectors; uint32_t secsize; char *state; sc = device_get_softc(dev); ld_info = device_get_ivars(dev); sc->ld_dev = dev; sc->ld_id = ld_info->ld_config.properties.ld.v.target_id; sc->ld_unit = device_get_unit(dev); sc->ld_info = ld_info; sc->ld_controller = device_get_softc(device_get_parent(dev)); sc->ld_flags = 0; sectors = ld_info->size; secsize = MFI_SECTOR_LEN; mtx_lock(&sc->ld_controller->mfi_io_lock); TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, sc, ld_link); mtx_unlock(&sc->ld_controller->mfi_io_lock); switch (ld_info->ld_config.params.state) { case MFI_LD_STATE_OFFLINE: state = "offline"; break; case MFI_LD_STATE_PARTIALLY_DEGRADED: state = "partially degraded"; break; case MFI_LD_STATE_DEGRADED: state = "degraded"; break; case MFI_LD_STATE_OPTIMAL: state = "optimal"; break; default: state = "unknown"; break; } device_printf(dev, "%juMB (%ju sectors) RAID volume '%s' is %s\n", sectors / (1024 * 1024 / secsize), sectors, ld_info->ld_config.properties.name, state); sc->ld_disk = disk_alloc(); sc->ld_disk->d_drv1 = sc; sc->ld_disk->d_maxsize = sc->ld_controller->mfi_max_io * secsize; sc->ld_disk->d_name = "mfid"; sc->ld_disk->d_open = mfi_disk_open; sc->ld_disk->d_close = mfi_disk_close; sc->ld_disk->d_strategy = mfi_disk_strategy; sc->ld_disk->d_dump = mfi_disk_dump; sc->ld_disk->d_unit = sc->ld_unit; sc->ld_disk->d_sectorsize = secsize; sc->ld_disk->d_mediasize = sectors * secsize; if (sc->ld_disk->d_mediasize >= (1 * 1024 * 1024)) { sc->ld_disk->d_fwheads = 255; sc->ld_disk->d_fwsectors = 63; } else { sc->ld_disk->d_fwheads = 64; sc->ld_disk->d_fwsectors = 32; } disk_create(sc->ld_disk, DISK_VERSION); return (0); }
static void * nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) { struct nvd_disk *ndisk; struct disk *disk; struct nvd_controller *ctrlr = ctrlr_arg; ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK); disk = disk_alloc(); disk->d_strategy = nvd_strategy; disk->d_ioctl = nvd_ioctl; disk->d_name = "nvd"; disk->d_drv1 = ndisk; disk->d_maxsize = nvme_ns_get_max_io_xfer_size(ns); disk->d_sectorsize = nvme_ns_get_sector_size(ns); disk->d_mediasize = (off_t)nvme_ns_get_size(ns); if (TAILQ_EMPTY(&disk_head)) disk->d_unit = 0; else disk->d_unit = TAILQ_LAST(&disk_head, disk_list)->disk->d_unit + 1; disk->d_flags = 0; if (nvme_ns_get_flags(ns) & NVME_NS_DEALLOCATE_SUPPORTED) disk->d_flags |= DISKFLAG_CANDELETE; if (nvme_ns_get_flags(ns) & NVME_NS_FLUSH_SUPPORTED) disk->d_flags |= DISKFLAG_CANFLUSHCACHE; /* ifdef used here to ease porting to stable branches at a later point. */ #ifdef DISKFLAG_UNMAPPED_BIO disk->d_flags |= DISKFLAG_UNMAPPED_BIO; #endif strlcpy(disk->d_ident, nvme_ns_get_serial_number(ns), sizeof(disk->d_ident)); #if __FreeBSD_version >= 900034 strlcpy(disk->d_descr, nvme_ns_get_model_number(ns), sizeof(disk->d_descr)); #endif disk_create(disk, DISK_VERSION); ndisk->ns = ns; ndisk->disk = disk; ndisk->cur_depth = 0; mtx_init(&ndisk->bioqlock, "NVD bioq lock", NULL, MTX_DEF); bioq_init(&ndisk->bioq); TASK_INIT(&ndisk->bioqtask, 0, nvd_bioq_process, ndisk); ndisk->tq = taskqueue_create("nvd_taskq", M_WAITOK, taskqueue_thread_enqueue, &ndisk->tq); taskqueue_start_threads(&ndisk->tq, 1, PI_DISK, "nvd taskq"); TAILQ_INSERT_TAIL(&disk_head, ndisk, global_tailq); TAILQ_INSERT_TAIL(&ctrlr->disk_head, ndisk, ctrlr_tailq); return (NULL); }
static int idad_attach(device_t dev) { struct ida_drive_info dinfo; struct disk_info info; struct idad_softc *drv; device_t parent; cdev_t dsk; int error; drv = (struct idad_softc *)device_get_softc(dev); parent = device_get_parent(dev); drv->controller = (struct ida_softc *)device_get_softc(parent); drv->unit = device_get_unit(dev); drv->drive = drv->controller->num_drives; drv->controller->num_drives++; error = ida_command(drv->controller, CMD_GET_LOG_DRV_INFO, &dinfo, sizeof(dinfo), drv->drive, 0, DMA_DATA_IN); if (error) { device_printf(dev, "CMD_GET_LOG_DRV_INFO failed\n"); return (ENXIO); } drv->cylinders = dinfo.ncylinders; drv->heads = dinfo.nheads; drv->sectors = dinfo.nsectors; drv->secsize = dinfo.secsize == 0 ? 512 : dinfo.secsize; drv->secperunit = dinfo.secperunit; /* XXX * other initialization */ device_printf(dev, "%uMB (%u sectors), blocksize=%d\n", drv->secperunit / ((1024 * 1024) / drv->secsize), drv->secperunit, drv->secsize); devstat_add_entry(&drv->stats, "idad", drv->unit, drv->secsize, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_STORARRAY| DEVSTAT_TYPE_IF_OTHER, DEVSTAT_PRIORITY_ARRAY); dsk = disk_create(drv->unit, &drv->disk, &id_ops); dsk->si_drv1 = drv; dsk->si_iosize_max = DFLTPHYS; /* XXX guess? */ /* * Set disk info, as it appears that all needed data is available already. * Setting the disk info will also cause the probing to start. */ bzero(&info, sizeof(info)); info.d_media_blksize = drv->secsize; /* mandatory */ info.d_media_blocks = drv->secperunit; info.d_secpertrack = drv->sectors; /* optional */ info.d_type = DTYPE_SCSI; info.d_nheads = drv->heads; info.d_ncylinders = drv->cylinders; info.d_secpercyl = drv->sectors * drv->heads; disk_setdiskinfo(&drv->disk, &info); return (0); }