Ejemplo n.º 1
0
int
sd_thin_pages(struct sd_softc *sc, int flags)
{
	struct scsi_vpd_hdr *pg;
	size_t len = 0;
	u_int8_t *pages;
	int i, score = 0;
	int rv;

	pg = dma_alloc(sizeof(*pg), (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg),
	    SI_PG_SUPPORTED, flags);
	if (rv != 0)
		goto done;

	len = _2btol(pg->page_length);

	dma_free(pg, sizeof(*pg));
	pg = dma_alloc(sizeof(*pg) + len, (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg) + len,
	    SI_PG_SUPPORTED, flags);
	if (rv != 0)
		goto done;

	pages = (u_int8_t *)(pg + 1);
	if (pages[0] != SI_PG_SUPPORTED) {
		rv = EIO;
		goto done;
	}

	for (i = 1; i < len; i++) {
		switch (pages[i]) {
		case SI_PG_DISK_LIMITS:
		case SI_PG_DISK_THIN:
			score++;
			break;
		}
	}

	if (score < 2)
		rv = EOPNOTSUPP;

 done:
	dma_free(pg, sizeof(*pg) + len);
	return (rv);
}
Ejemplo n.º 2
0
int
sd_ioctl_inquiry(struct sd_softc *sc, struct dk_inquiry *di)
{
	struct scsi_vpd_serial *vpd;

	vpd = dma_alloc(sizeof(*vpd), PR_WAITOK | PR_ZERO);

	bzero(di, sizeof(struct dk_inquiry));
	scsi_strvis(di->vendor, sc->sc_link->inqdata.vendor,
	    sizeof(sc->sc_link->inqdata.vendor));
	scsi_strvis(di->product, sc->sc_link->inqdata.product,
	    sizeof(sc->sc_link->inqdata.product));
	scsi_strvis(di->revision, sc->sc_link->inqdata.revision,
	    sizeof(sc->sc_link->inqdata.revision));

	/* the serial vpd page is optional */
	if (scsi_inquire_vpd(sc->sc_link, vpd, sizeof(*vpd),
	    SI_PG_SERIAL, 0) == 0)
		scsi_strvis(di->serial, vpd->serial, sizeof(vpd->serial));
	else
		strlcpy(di->serial, "(unknown)", sizeof(vpd->serial));

	dma_free(vpd, sizeof(*vpd));
	return (0);
}
Ejemplo n.º 3
0
int
sd_vpd_thin(struct sd_softc *sc, int flags)
{
	struct scsi_vpd_disk_thin *pg;
	int rv;

	pg = dma_alloc(sizeof(*pg), (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg),
	    SI_PG_DISK_THIN, flags);
	if (rv != 0)
		goto done;

#ifdef notyet
	if (ISSET(pg->flags, VPD_DISK_THIN_TPU))
		sc->sc_delete = sd_unmap;
	else if (ISSET(pg->flags, VPD_DISK_THIN_TPWS)) {
		sc->sc_delete = sd_write_same_16;
		sc->params.unmap_descs = 1; /* WRITE SAME 16 only does one */
	} else
		rv = EOPNOTSUPP;
#endif

 done:
	dma_free(pg, sizeof(*pg));
	return (rv);
}
Ejemplo n.º 4
0
int
sd_vpd_block_limits(struct sd_softc *sc, int flags)
{
	struct scsi_vpd_disk_limits *pg;
	int rv;

	pg = dma_alloc(sizeof(*pg), (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg),
	    SI_PG_DISK_LIMITS, flags);
	if (rv != 0)
		goto done;

	if (_2btol(pg->hdr.page_length) == SI_PG_DISK_LIMITS_LEN_THIN) {
		sc->params.unmap_sectors = _4btol(pg->max_unmap_lba_count);
		sc->params.unmap_descs = _4btol(pg->max_unmap_desc_count);
	} else
		rv = EOPNOTSUPP;

 done:
	dma_free(pg, sizeof(*pg));
	return (rv);
}
Ejemplo n.º 5
0
int
emc_sp_info(struct emc_softc *sc)
{
	struct emc_vpd_sp_info pg;
	int error;

	error = scsi_inquire_vpd(sc->sc_path.p_link, &pg, sizeof(pg),
	    EMC_VPD_SP_INFO, scsi_autoconf);
	if (error != 0)
                return (error);

	sc->sc_sp = pg.current_sp;
	sc->sc_port = pg.port;
	sc->sc_lun_state = pg.lun_state;

        return (0);
}
Ejemplo n.º 6
0
int
emc_sp_info(struct emc_softc *sc, int *sp)
{
	struct emc_vpd_sp_info *pg = sc->sc_pg;
	int error;

	error = scsi_inquire_vpd(sc->sc_path.p_link, pg, sizeof(*pg),
	    EMC_VPD_SP_INFO, scsi_autoconf);
	if (error != 0)
		return (error);

	*sp = pg->current_sp;

	printf("%s: SP-%c port %d\n", DEVNAME(sc), pg->current_sp + 'A',
	    pg->port);

	return (0);
}
Ejemplo n.º 7
0
int
emc_sp_info(struct emc_softc *sc)
{
	struct emc_vpd_sp_info *pg;
	int error;

	pg = dma_alloc(sizeof(*pg), PR_WAITOK);

	error = scsi_inquire_vpd(sc->sc_path.p_link, &pg, sizeof(pg),
	    EMC_VPD_SP_INFO, scsi_autoconf);
	if (error != 0)
		goto done;

	sc->sc_sp = pg->current_sp;
	sc->sc_port = pg->port;
	sc->sc_lun_state = pg->lun_state;

	error = 0;
done:
	dma_free(pg, sizeof(*pg));
	return (error);
}