int astattach(struct ata_device *atadev) { struct ast_softc *stp; struct ast_readposition position; dev_t dev; stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO); if (!stp) { ata_prtdev(atadev, "out of memory\n"); return 0; } stp->device = atadev; stp->lun = ata_get_lun(&ast_lun_map); ata_set_name(atadev, "ast", stp->lun); bufq_init(&stp->queue); if (ast_sense(stp)) { free(stp, M_AST); return 0; } if (!strcmp(atadev->param->model, "OnStream DI-30")) { struct ast_transferpage transfer; struct ast_identifypage identify; stp->flags |= F_ONSTREAM; bzero(&transfer, sizeof(struct ast_transferpage)); ast_mode_sense(stp, ATAPI_TAPE_TRANSFER_PAGE, &transfer, sizeof(transfer)); bzero(&identify, sizeof(struct ast_identifypage)); ast_mode_sense(stp, ATAPI_TAPE_IDENTIFY_PAGE, &identify, sizeof(identify)); strncpy(identify.ident, "FBSD", 4); ast_mode_select(stp, &identify, sizeof(identify)); ast_read_position(stp, 0, &position); } devstat_add_entry(&stp->stats, "ast", stp->lun, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_SEQUENTIAL | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_TAPE); dev = make_dev(&ast_cdevsw, dkmakeminor(stp->lun, 0, 0), UID_ROOT, GID_OPERATOR, 0640, "ast%d", stp->lun); dev->si_drv1 = stp; dev->si_iosize_max = 256 * DEV_BSIZE; stp->dev1 = dev; dev = make_dev(&ast_cdevsw, dkmakeminor(stp->lun, 0, 1), UID_ROOT, GID_OPERATOR, 0640, "nast%d", stp->lun); dev->si_drv1 = stp; dev->si_iosize_max = 256 * DEV_BSIZE; stp->dev2 = dev; stp->device->flags |= ATA_D_MEDIA_CHANGED; ast_describe(stp); atadev->driver = stp; return 1; }
static cam_status ptctor(struct cam_periph *periph, void *arg) { struct pt_softc *softc; struct ccb_getdev *cgd; cgd = (struct ccb_getdev *)arg; if (periph == NULL) { kprintf("ptregister: periph was NULL!!\n"); return(CAM_REQ_CMP_ERR); } if (cgd == NULL) { kprintf("ptregister: no getdev CCB, can't register device\n"); return(CAM_REQ_CMP_ERR); } softc = kmalloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO); LIST_INIT(&softc->pending_ccbs); softc->state = PT_STATE_NORMAL; bioq_init(&softc->bio_queue); softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000; periph->softc = softc; cam_periph_unlock(periph); cam_extend_set(ptperiphs, periph->unit_number, periph); devstat_add_entry(&softc->device_stats, "pt", periph->unit_number, 0, DEVSTAT_NO_BLOCKSIZE, SID_TYPE(&cgd->inq_data) | DEVSTAT_TYPE_IF_SCSI, DEVSTAT_PRIORITY_OTHER); make_dev(&pt_ops, periph->unit_number, UID_ROOT, GID_OPERATOR, 0600, "%s%d", periph->periph_name, periph->unit_number); cam_periph_lock(periph); /* * Add async callbacks for bus reset and * bus device reset calls. I don't bother * checking if this fails as, in most cases, * the system will function just fine without * them and the only alternative would be to * not attach the device on failure. */ xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE, ptasync, periph, periph->path); /* Tell the user we've attached to the device */ xpt_announce_periph(periph, NULL); return(CAM_REQ_CMP); }
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 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; }
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; 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 cam_status ptctor(struct cam_periph *periph, void *arg) { struct pt_softc *softc; struct ccb_setasync csa; struct ccb_getdev *cgd; cgd = (struct ccb_getdev *)arg; if (periph == NULL) { printf("ptregister: periph was NULL!!\n"); return(CAM_REQ_CMP_ERR); } if (cgd == NULL) { printf("ptregister: no getdev CCB, can't register device\n"); return(CAM_REQ_CMP_ERR); } softc = (struct pt_softc *)malloc(sizeof(*softc),M_DEVBUF,M_NOWAIT); if (softc == NULL) { printf("daregister: Unable to probe new device. " "Unable to allocate softc\n"); return(CAM_REQ_CMP_ERR); } bzero(softc, sizeof(*softc)); LIST_INIT(&softc->pending_ccbs); softc->state = PT_STATE_NORMAL; bioq_init(&softc->bio_queue); softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000; periph->softc = softc; devstat_add_entry(&softc->device_stats, "pt", periph->unit_number, 0, DEVSTAT_NO_BLOCKSIZE, SID_TYPE(&cgd->inq_data) | DEVSTAT_TYPE_IF_SCSI, DEVSTAT_PRIORITY_OTHER); softc->dev = make_dev(&pt_cdevsw, periph->unit_number, UID_ROOT, GID_OPERATOR, 0600, "%s%d", periph->periph_name, periph->unit_number); softc->dev->si_drv1 = periph; /* * Add async callbacks for bus reset and * bus device reset calls. I don't bother * checking if this fails as, in most cases, * the system will function just fine without * them and the only alternative would be to * not attach the device on failure. */ xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5); csa.ccb_h.func_code = XPT_SASYNC_CB; csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE; csa.callback = ptasync; csa.callback_arg = periph; xpt_action((union ccb *)&csa); /* Tell the user we've attached to the device */ xpt_announce_periph(periph, NULL); return(CAM_REQ_CMP); }
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; }
int acdattach(struct atapi *ata, int unit, struct atapi_params *ap, int debug) { struct acd *cdp; struct atapires result; struct changer *chp; int i, count; if (acdnlun >= NUNIT) { printf("wcd: too many units\n"); return 0; } if (!atapi_request_immediate) { printf("wcd: configuration error, ATAPI code not present!\n"); return 0; } if ((cdp = acd_init_lun(ata, unit, ap, acdnlun, NULL)) == NULL) { printf("wcd: out of memory\n"); return 0; } acdtab[acdnlun] = cdp; if (debug) { cdp->flags |= F_DEBUG; atapi_dump(cdp->ata->ctrlr, cdp->lun, "info", ap, sizeof(*ap)); } /* Get drive capabilities, some drives needs this repeated */ for (count = 0 ; count < 5 ; count++) { result = atapi_request_immediate(ata, unit, ATAPI_MODE_SENSE, 0, ATAPI_CDROM_CAP_PAGE, 0, 0, 0, 0, sizeof(cdp->cap)>>8, sizeof(cdp->cap), 0, 0, 0, 0, 0, 0, 0, (char *)&cdp->cap, sizeof(cdp->cap)); if (result.code == 0 || result.code == RES_UNDERRUN) break; } /* Some drives have shorter capabilities page. */ if (result.code == RES_UNDERRUN) result.code = 0; if (result.code == 0) { cdp->cap.max_speed = ntohs(cdp->cap.max_speed); cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels); cdp->cap.buf_size = ntohs(cdp->cap.buf_size); cdp->cap.cur_speed = ntohs(cdp->cap.cur_speed); acd_describe(cdp); if (cdp->flags & F_DEBUG) atapi_dump(cdp->ata->ctrlr, cdp->lun, "cap", &cdp->cap, sizeof(cdp->cap)); } /* If this is a changer device, allocate the neeeded lun's */ if (cdp->cap.mech == MST_MECH_CHANGER) { char string[16]; struct acd *tmpcdp = cdp; chp = malloc(sizeof(struct changer), M_TEMP, M_NOWAIT | M_ZERO); if (chp == NULL) { printf("wcd: out of memory\n"); return 0; } result = atapi_request_immediate(ata, unit, ATAPI_MECH_STATUS, 0, 0, 0, 0, 0, 0, 0, sizeof(struct changer)>>8, sizeof(struct changer), 0, 0, 0, 0, 0, 0, (char *)chp, sizeof(struct changer)); if (cdp->flags & F_DEBUG) { printf("result.code=%d curr=%02x slots=%d len=%d\n", result.code, chp->current_slot, chp->slots, htons(chp->table_length)); } if (result.code == RES_UNDERRUN) result.code = 0; if (result.code == 0) { chp->table_length = htons(chp->table_length); for (i = 0; i < chp->slots && acdnlun < NUNIT; i++) { if (i > 0) { tmpcdp = acd_init_lun(ata, unit, ap, acdnlun, cdp->device_stats); if (!tmpcdp) { printf("wcd: out of memory\n"); return 0; } } tmpcdp->slot = i; tmpcdp->changer_info = chp; printf("wcd%d: changer slot %d %s\n", acdnlun, i, (chp->slot[i].present ? "disk present" : "no disk")); acdtab[acdnlun++] = tmpcdp; } if (acdnlun >= NUNIT) { printf("wcd: too many units\n"); return 0; } } sprintf(string, "wcd%d-", cdp->lun); devstat_add_entry(cdp->device_stats, string, tmpcdp->lun, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_CD); }
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 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); }
int ida_attach_drives(int cntlr) { struct ida_ctl *ctlp = idadata[cntlr]; qcb_t qcb; qcb_t *qcbp = &qcb; struct ida_drv *drv; int drive; int unit; /* prepare to interrogate the drives */ bzero(qcbp, sizeof(qcb_t)); qcbp->req.command = IDA_GET_DRV_INFO; qcbp->paddr = vtophys(qcbp); if (PCI_CONTROLLER(ctlp)) { qcbp->hdr.priority = 0x00; qcbp->hdr.flags = 0x24; } else { qcbp->hdr.priority = IDA_DEF_PRIORITY; qcbp->hdr.flags = 0x12; } qcbp->req.bcount = 1; qcbp->req.sgcount = 1; qcbp->sglist[0].len = sizeof(ida_buf); qcbp->sglist[0].addr = vtophys(&ida_buf); for (drive = 0 ; drive < ctlp->num_drvs ; drive++) { qcbp->hdr.drive = drive; if (ida_submit_wait(cntlr, qcbp, sizeof(struct ida_qcb))) { printf("ida%d: ida_submit_wait failed on IDA_GET_DRV_INFO\n", cntlr); return 0; } if (!PCI_CONTROLLER(ctlp)) { if (ctlp->com_status != IDA_COMPL_OK) { printf("ida%d: bad status 0x%02x from IDA_GET_DRV_INFO\n", cntlr, ctlp->com_status); return 0; } } if ((drv = malloc(sizeof(struct ida_drv), M_TEMP, M_NOWAIT)) == NULL) { printf("ida%d: unable to allocate drive structure\n", cntlr); return 0; } bzero(drv, sizeof(struct ida_drv)); drv->ctl_unit = cntlr; drv->drv_unit = drive; drv->drv_info = ida_buf.drv; drv->flags |= ID_INIT; unit = id_unit; id_unit++; /* XXX unsure if this is the right way to do things */ id_drive[unit] = drv; printf("ida%d: unit %d (id%d): <%s>\n", cntlr, drive, unit, "Compaq Logical Drive"); printf("id%d: %luMB (%lu total sec), ", unit, (u_long)(u_unpack(drv->drv_info.secperunit) / 2048) * (u_unpack(drv->drv_info.secsize) / 512), (u_long)u_unpack(drv->drv_info.secperunit)); printf("%lu cyl, %lu head, %lu sec, bytes/sec %lu\n", (u_long)u_unpack(drv->drv_info.ncylinders), (u_long)u_unpack(drv->drv_info.ntracks), (u_long)u_unpack(drv->drv_info.nsectors), (u_long)u_unpack(drv->drv_info.secsize)); /* * Export the drive to the devstat interface. */ devstat_add_entry(&drv->dk_stats, "id", unit, (u_int32_t)drv->drv_info.secsize, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, DEVSTAT_PRIORITY_DA); #ifdef IDADEBUG if (ida_debug & IDA_SHOWMISC) { printf("ida%d: drive %d secsize=%d secperunit=%d ncylinders=%d ntracks=%d\n", unit, drive, u_unpack(ida_buf.drv.secsize), u_unpack(ida_buf.drv.secperunit), u_unpack(ida_buf.drv.ncylinders), u_unpack(ida_buf.drv.ntracks)); printf(" signature=0x%02x psectors=%d wprecomp=%d max_acc=%d control=0x%02x\n", u_unpack(ida_buf.drv.signature), u_unpack(ida_buf.drv.psectors), u_unpack(ida_buf.drv.wprecomp), u_unpack(ida_buf.drv.max_acc), u_unpack(ida_buf.drv.control)); printf(" pcylinders=%d ptracks=%d landing_zone=%d nsectors=%d checksum=0x%02x\n", u_unpack(ida_buf.drv.pcylinders), u_unpack(ida_buf.drv.ptracks), u_unpack(ida_buf.drv.landing_zone), u_unpack(ida_buf.drv.nsectors), u_unpack(ida_buf.drv.checksum)); } #endif } return 1; }