示例#1
0
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));

}
示例#2
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);
}
示例#3
0
文件: cfi_disk.c 项目: 2asoft/freebsd
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;
}
示例#4
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);
}
示例#5
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);
}
示例#6
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);
}
示例#7
0
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;
}
示例#8
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;

    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;
}
示例#9
0
文件: nvd.c 项目: JabirTech/Source
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);
}
示例#10
0
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);
}
示例#11
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);
}
示例#12
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);
}
示例#13
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;
}
示例#14
0
文件: nvd.c 项目: rchander/freebsd
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);
}
示例#15
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 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;
}