Example #1
0
static int
afd_open(struct disk *dp)
{
    device_t dev = dp->d_drv1;
    struct ata_device *atadev = device_get_softc(dev);
    struct afd_softc *fdp = device_get_ivars(dev);

    if (!fdp) 
	return ENXIO;
    if (!device_is_attached(dev))
	return EBUSY;

    afd_test_ready(dev);
    afd_prevent_allow(dev, 1);

    if (afd_sense(dev))
	device_printf(dev, "sense media type failed\n");
    atadev->flags &= ~ATA_D_MEDIA_CHANGED;

    if (!fdp->mediasize)
	return ENXIO;

    fdp->disk->d_sectorsize = fdp->sectorsize;
    fdp->disk->d_mediasize = fdp->mediasize;
    fdp->disk->d_fwsectors = fdp->sectors;
    fdp->disk->d_fwheads = fdp->heads;
    return 0;
}
Example #2
0
static int
afd_open(struct dev_open_args *ap)
{
    device_t dev = ap->a_head.a_dev->si_drv1;
    struct ata_device *atadev = device_get_softc(dev);
    struct afd_softc *fdp = device_get_ivars(dev);
    struct disk_info info;

    if (!fdp) 
	return ENXIO;
    if (!device_is_attached(dev))
	return EBUSY;

    afd_test_ready(dev);
    afd_prevent_allow(dev, 1);

    if (afd_sense(dev))
	device_printf(dev, "sense media type failed\n");
    atadev->flags &= ~ATA_D_MEDIA_CHANGED;

    if (!fdp->mediasize)
	return ENXIO;

    bzero(&info, sizeof(info));
    info.d_media_blksize = fdp->sectorsize;	/* mandatory */
    info.d_media_size = fdp->mediasize;		/* (this is in bytes) */

    info.d_secpertrack = fdp->sectors;		/* optional */
    info.d_nheads = fdp->heads;
    info.d_ncylinders =
	   ((fdp->mediasize/fdp->sectorsize)/fdp->sectors)/fdp->heads;
    info.d_secpercyl = fdp->sectors * fdp->heads;

    disk_setdiskinfo(&fdp->disk, &info);
    return 0;
}
Example #3
0
static int 
afd_sense(device_t dev)
{
    struct ata_device *atadev = device_get_softc(dev);
    struct afd_softc *fdp = device_get_ivars(dev);
    struct afd_capacity capacity;
    struct afd_capacity_big capacity_big;
    struct afd_capabilities capabilities;
    int8_t ccb1[16] = { ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0,
                        0, 0, 0, 0, 0, 0, 0, 0 };
    int8_t ccb2[16] = { ATAPI_READ_CAPACITY_16, 0x10, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, sizeof(struct afd_capacity_big) & 0xff, 0, 0 };
    int8_t ccb3[16] = { ATAPI_MODE_SENSE_BIG, 0, ATAPI_REWRITEABLE_CAP_PAGE,
		        0, 0, 0, 0, sizeof(struct afd_capabilities) >> 8,
		        sizeof(struct afd_capabilities) & 0xff,
			0, 0, 0, 0, 0, 0, 0 };
    int timeout = 20;
    int error, count;

    fdp->mediasize = 0;

    /* wait for device to get ready */
    while ((error = afd_test_ready(dev)) && timeout--) {
	DELAY(100000);
    }
    if (error == EBUSY)
	return 1;

    /* The IOMEGA Clik! doesn't support reading the cap page, fake it */
    if (!strncmp(atadev->param.model, "IOMEGA Clik!", 12)) {
	fdp->heads = 1;
	fdp->sectors = 2;
	fdp->mediasize = 39441 * 1024;
	fdp->sectorsize = 512;
	afd_test_ready(dev);
	return 0;
    }

    /* get drive capacity */
    if (!ata_atapicmd(dev, ccb1, (caddr_t)&capacity,
		      sizeof(struct afd_capacity), ATA_R_READ, 30)) {
	fdp->heads = 16;
	fdp->sectors = 63;
	fdp->sectorsize = be32toh(capacity.blocksize);
	fdp->mediasize = (u_int64_t)be32toh(capacity.capacity)*fdp->sectorsize; 
	afd_test_ready(dev);
	return 0;
    }

    /* get drive capacity big */
    if (!ata_atapicmd(dev, ccb2, (caddr_t)&capacity_big,
		      sizeof(struct afd_capacity_big),
		      ATA_R_READ | ATA_R_QUIET, 30)) {
	fdp->heads = 16;
	fdp->sectors = 63;
	fdp->sectorsize = be32toh(capacity_big.blocksize);
	fdp->mediasize = be64toh(capacity_big.capacity)*fdp->sectorsize;
	afd_test_ready(dev);
	return 0;
    }

    /* get drive capabilities, some bugridden drives needs this repeated */
    for (count = 0 ; count < 5 ; count++) {
	if (!ata_atapicmd(dev, ccb3, (caddr_t)&capabilities,
			  sizeof(struct afd_capabilities), ATA_R_READ, 30) &&
	    capabilities.page_code == ATAPI_REWRITEABLE_CAP_PAGE) {
	    fdp->heads = capabilities.heads;
	    fdp->sectors = capabilities.sectors;
	    fdp->sectorsize = be16toh(capabilities.sector_size);
	    fdp->mediasize = be16toh(capabilities.cylinders) *
			     fdp->heads * fdp->sectors * fdp->sectorsize;
	    if (!capabilities.medium_type)
		fdp->mediasize = 0;
	    return 0;
	}
    }
    return 1;
}

static int
afd_prevent_allow(device_t dev, int lock)
{
    struct ata_device *atadev = device_get_softc(dev);
    int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
		       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    if (!strncmp(atadev->param.model, "IOMEGA Clik!", 12))
	return 0;
    return ata_atapicmd(dev, ccb, NULL, 0, 0, 30);
}

static int
afd_test_ready(device_t dev)
{
    int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
		       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    return ata_atapicmd(dev, ccb, NULL, 0, 0, 30);
}