Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
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;
}
Beispiel #5
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;
}
Beispiel #6
0
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;
}
Beispiel #7
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);
}
Beispiel #8
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;
}
Beispiel #9
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);
    }
Beispiel #10
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);
}
Beispiel #11
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);
}
Beispiel #12
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;
}