Ejemplo n.º 1
0
void
safte_attach(struct device *parent, struct device *self, void *aux)
{
	struct safte_softc		*sc = (struct safte_softc *)self;
	struct scsi_attach_args		*sa = aux;
	int				i = 0;

	sc->sc_link = sa->sa_sc_link;
	sa->sa_sc_link->device_softc = sc;
	rw_init(&sc->sc_lock, DEVNAME(sc));

	printf("\n");

	sc->sc_encbuf = NULL;
	sc->sc_nsensors = 0;
#if NBIO > 0
	sc->sc_nslots = 0;
#endif

	if (safte_read_config(sc) != 0) {
		printf("%s: unable to read enclosure configuration\n",
		    DEVNAME(sc));
		return;
	}

	if (sc->sc_nsensors > 0) {
		sc->sc_sensortask = sensor_task_register(sc,
		    safte_read_encstat, 10);
		if (sc->sc_sensortask == NULL) {
			printf("%s: unable to register update task\n",
			    DEVNAME(sc));
			sc->sc_nsensors = sc->sc_ntemps = 0;
			free(sc->sc_sensors, M_DEVBUF);
		} else {
			for (i = 0; i < sc->sc_nsensors; i++)
				sensor_attach(&sc->sc_sensordev, 
				    &sc->sc_sensors[i].se_sensor);
			sensordev_install(&sc->sc_sensordev);
		}
	}

#if NBIO > 0
	if (sc->sc_nslots > 0 &&
	    bio_register(self, safte_ioctl) != 0) {
		printf("%s: unable to register ioctl with bio\n", DEVNAME(sc));
		sc->sc_nslots = 0;
	} else
		i++;
#endif

	if (i) /* if we're doing something, then preinit encbuf and sensors */
		safte_read_encstat(sc);
	else {
		free(sc->sc_encbuf, M_DEVBUF);
		sc->sc_encbuf = NULL;
	}
}
Ejemplo n.º 2
0
/*
 * The routine called by the adapter boards to get all their
 * devices configured in.
 */
void
scsibusattach(struct device *parent, struct device *self, void *aux)
{
	struct scsibus_softc		*sb = (struct scsibus_softc *)self;
	struct scsibus_attach_args	*saa = aux;
	struct scsi_link		*sc_link_proto = saa->saa_sc_link;
	int				nbytes, i;

	if (!cold)
		scsi_autoconf = 0;

	sc_link_proto->scsibus = sb->sc_dev.dv_unit;
	sb->adapter_link = sc_link_proto;
	if (sb->adapter_link->adapter_buswidth == 0)
		sb->adapter_link->adapter_buswidth = 8;
	sb->sc_buswidth = sb->adapter_link->adapter_buswidth;
	if (sb->adapter_link->luns == 0)
		sb->adapter_link->luns = 8;

	printf(": %d targets\n", sb->sc_buswidth);

	/* Initialize shared data. */
	scsi_init();

	nbytes = sb->sc_buswidth * sizeof(struct scsi_link **);
	sb->sc_link = malloc(nbytes, M_DEVBUF, M_NOWAIT);
	if (sb->sc_link == NULL)
		panic("scsibusattach: can't allocate target links");
	nbytes = sb->adapter_link->luns * sizeof(struct scsi_link *);
	for (i = 0; i < sb->sc_buswidth; i++) {
		sb->sc_link[i] = malloc(nbytes, M_DEVBUF, M_NOWAIT);
		if (sb->sc_link[i] == NULL)
			panic("scsibusattach: can't allocate lun links");
		bzero(sb->sc_link[i], nbytes);
	}

#if NBIO > 0
	if (bio_register(&sb->sc_dev, scsibus_bioctl) != 0)
		printf("%s: unable to register bio\n", sb->sc_dev.dv_xname);
#endif

	scsi_probe_bus(sb);
}
Ejemplo n.º 3
0
/*
 * The routine called by the adapter boards to get all their
 * devices configured in.
 */
void
scsibusattach(struct device *parent, struct device *self, void *aux)
{
	struct scsibus_softc		*sb = (struct scsibus_softc *)self;
	struct scsibus_attach_args	*saa = aux;
	struct scsi_link		*sc_link_proto = saa->saa_sc_link;

	if (!cold)
		scsi_autoconf = 0;

	sc_link_proto->bus = sb;
	sc_link_proto->scsibus = sb->sc_dev.dv_unit;
	sb->adapter_link = sc_link_proto;
	if (sb->adapter_link->adapter_buswidth == 0)
		sb->adapter_link->adapter_buswidth = 8;
	sb->sc_buswidth = sb->adapter_link->adapter_buswidth;
	if (sb->adapter_link->luns == 0)
		sb->adapter_link->luns = 8;

	printf(": %d targets", sb->sc_buswidth);
	if (sb->adapter_link->adapter_target < sb->sc_buswidth)
		printf(", initiator %d", sb->adapter_link->adapter_target);
	if (sb->adapter_link->port_wwn != 0x0 &&
	    sb->adapter_link->node_wwn != 0x0) {
		printf(", WWPN %016llx, WWNN %016llx",
		    sb->adapter_link->port_wwn, sb->adapter_link->node_wwn);
	}
	printf("\n");

	/* Initialize shared data. */
	scsi_init();

	SLIST_INIT(&sb->sc_link);

#if NBIO > 0
	if (bio_register(&sb->sc_dev, scsibus_bioctl) != 0)
		printf("%s: unable to register bio\n", sb->sc_dev.dv_xname);
#endif

	scsi_probe_bus(sb);
}
Ejemplo n.º 4
0
Archivo: cac.c Proyecto: ryo/netbsd-src
/*
 * Initialise our interface to the controller.
 */
int
cac_init(struct cac_softc *sc, const char *intrstr, int startfw)
{
	struct cac_controller_info cinfo;
	int error, rseg, size, i;
	bus_dma_segment_t seg;
	struct cac_ccb *ccb;
	char firm[8];

	if (intrstr != NULL)
		aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	SIMPLEQ_INIT(&sc->sc_ccb_free);
	SIMPLEQ_INIT(&sc->sc_ccb_queue);
	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);
	cv_init(&sc->sc_ccb_cv, "cacccb");

        size = sizeof(struct cac_ccb) * CAC_MAX_CCBS;

	if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1,
	    &rseg, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to allocate CCBs, error = %d\n",
		    error);
		return (-1);
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
	    (void **)&sc->sc_ccbs,
	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to map CCBs, error = %d\n",
		    error);
		return (-1);
	}

	if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
	    BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to create CCB DMA map, error = %d\n",
		    error);
		return (-1);
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ccbs,
	    size, NULL, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to load CCB DMA map, error = %d\n",
		    error);
		return (-1);
	}

	sc->sc_ccbs_paddr = sc->sc_dmamap->dm_segs[0].ds_addr;
	memset(sc->sc_ccbs, 0, size);
	ccb = (struct cac_ccb *)sc->sc_ccbs;

	for (i = 0; i < CAC_MAX_CCBS; i++, ccb++) {
		/* Create the DMA map for this CCB's data */
		error = bus_dmamap_create(sc->sc_dmat, CAC_MAX_XFER,
		    CAC_SG_SIZE, CAC_MAX_XFER, 0,
		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
		    &ccb->ccb_dmamap_xfer);

		if (error) {
			aprint_error_dev(sc->sc_dev, "can't create ccb dmamap (%d)\n",
			    error);
			break;
		}

		ccb->ccb_flags = 0;
		ccb->ccb_paddr = sc->sc_ccbs_paddr + i * sizeof(struct cac_ccb);
		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_chain);
	}

	/* Start firmware background tasks, if needed. */
	if (startfw) {
		if (cac_cmd(sc, CAC_CMD_START_FIRMWARE, &cinfo, sizeof(cinfo),
		    0, 0, CAC_CCB_DATA_IN, NULL)) {
			aprint_error_dev(sc->sc_dev, "CAC_CMD_START_FIRMWARE failed\n");
			return (-1);
		}
	}

	if (cac_cmd(sc, CAC_CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo), 0, 0,
	    CAC_CCB_DATA_IN, NULL)) {
		aprint_error_dev(sc->sc_dev, "CAC_CMD_GET_CTRL_INFO failed\n");
		return (-1);
	}

	strlcpy(firm, cinfo.firm_rev, 4+1);
	printf("%s: %d channels, firmware <%s>\n", device_xname(sc->sc_dev),
	    cinfo.scsi_chips, firm);

	/* Limit number of units to size of our sc_unitmask */
	sc->sc_nunits = cinfo.num_drvs;
	if (sc->sc_nunits > sizeof(sc->sc_unitmask) * NBBY)
		sc->sc_nunits = sizeof(sc->sc_unitmask) * NBBY;

	/* Attach our units */
	sc->sc_unitmask = 0;
	cac_rescan(sc->sc_dev, "cac", 0);

	/* Set our `shutdownhook' before we start any device activity. */
	if (cac_sdh == NULL)
		cac_sdh = shutdownhook_establish(cac_shutdown, NULL);

	mutex_enter(&sc->sc_mutex);
	(*sc->sc_cl.cl_intr_enable)(sc, CAC_INTR_ENABLE);
	mutex_exit(&sc->sc_mutex);

#if NBIO > 0
	if (bio_register(sc->sc_dev, cac_ioctl) != 0)
		aprint_error_dev(sc->sc_dev, "controller registration failed");
	else
		sc->sc_ioctl = cac_ioctl;
	if (cac_create_sensors(sc) != 0)
		aprint_error_dev(sc->sc_dev, "unable to create sensors\n");
#endif

	return (0);
}
static void
ld_ataraid_attach(device_t parent, device_t self, void *aux)
{
	struct ld_ataraid_softc *sc = device_private(self);
	struct ld_softc *ld = &sc->sc_ld;
	struct ataraid_array_info *aai = aux;
	struct ataraid_disk_info *adi = NULL;
	const char *level;
	struct vnode *vp;
	char unklev[32];
	u_int i;

	ld->sc_dv = self;

	if (ld_ataraid_initialized == 0) {
		ld_ataraid_initialized = 1;
		pool_init(&ld_ataraid_cbufpl, sizeof(struct cbuf), 0,
		    0, 0, "ldcbuf", NULL, IPL_BIO);
	}

	sc->sc_aai = aai;	/* this data persists */

	ld->sc_maxxfer = MAXPHYS * aai->aai_width;	/* XXX */
	ld->sc_secperunit = aai->aai_capacity;
	ld->sc_secsize = 512;				/* XXX */
	ld->sc_maxqueuecnt = 128;			/* XXX */
	ld->sc_dump = ld_ataraid_dump;

	switch (aai->aai_level) {
	case AAI_L_SPAN:
		level = "SPAN";
		ld->sc_start = ld_ataraid_start_span;
		sc->sc_iodone = ld_ataraid_iodone_raid0;
		break;

	case AAI_L_RAID0:
		level = "RAID-0";
		ld->sc_start = ld_ataraid_start_raid0;
		sc->sc_iodone = ld_ataraid_iodone_raid0;
		break;

	case AAI_L_RAID1:
		level = "RAID-1";
		ld->sc_start = ld_ataraid_start_raid0;
		sc->sc_iodone = ld_ataraid_iodone_raid0;
		break;

	case AAI_L_RAID0 | AAI_L_RAID1:
		level = "RAID-10";
		ld->sc_start = ld_ataraid_start_raid0;
		sc->sc_iodone = ld_ataraid_iodone_raid0;
		break;

	default:
		snprintf(unklev, sizeof(unklev), "<unknown level 0x%x>",
		    aai->aai_level);
		level = unklev;
	}

	aprint_naive(": ATA %s array\n", level);
	aprint_normal(": %s ATA %s array\n",
	    ata_raid_type_name(aai->aai_type), level);

	if (ld->sc_start == NULL) {
		aprint_error_dev(ld->sc_dv, "unsupported array type\n");
		return;
	}

	/*
	 * We get a geometry from the device; use it.
	 */
	ld->sc_nheads = aai->aai_heads;
	ld->sc_nsectors = aai->aai_sectors;
	ld->sc_ncylinders = aai->aai_cylinders;

	/*
	 * Configure all the component disks.
	 */
	for (i = 0; i < aai->aai_ndisks; i++) {
		adi = &aai->aai_disks[i];
		vp = ata_raid_disk_vnode_find(adi);
		if (vp == NULL) {
			/*
			 * XXX This is bogus.  We should just mark the
			 * XXX component as FAILED, and write-back new
			 * XXX config blocks.
			 */
			break;
		}
		sc->sc_vnodes[i] = vp;
	}
	if (i == aai->aai_ndisks) {
		ld->sc_flags = LDF_ENABLED;
		goto finish;
	}

	for (i = 0; i < aai->aai_ndisks; i++) {
		vp = sc->sc_vnodes[i];
		sc->sc_vnodes[i] = NULL;
		if (vp != NULL)
			(void) vn_close(vp, FREAD|FWRITE, NOCRED);
	}

 finish:
#if NBIO > 0
	if (bio_register(self, ld_ataraid_bioctl) != 0)
		panic("%s: bioctl registration failed\n",
		    device_xname(ld->sc_dv));
#endif
	ldattach(ld);
}
Ejemplo n.º 6
0
/*
 * Initialise our interface to the controller.
 */
int
cac_init(struct cac_softc *sc, int startfw)
{
	struct scsibus_attach_args saa;
	struct cac_controller_info cinfo;
	int error, rseg, size, i;
	bus_dma_segment_t seg[1];
	struct cac_ccb *ccb;

	SIMPLEQ_INIT(&sc->sc_ccb_free);
	SIMPLEQ_INIT(&sc->sc_ccb_queue);

        size = sizeof(struct cac_ccb) * CAC_MAX_CCBS;

	if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, seg, 1,
	    &rseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) != 0) {
		printf("%s: unable to allocate CCBs, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, seg, rseg, size,
	    &sc->sc_ccbs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
		printf("%s: unable to map CCBs, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
	    BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
		printf("%s: unable to create CCB DMA map, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ccbs,
	    size, NULL, BUS_DMA_NOWAIT)) != 0) {
		printf("%s: unable to load CCB DMA map, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	sc->sc_ccbs_paddr = sc->sc_dmamap->dm_segs[0].ds_addr;
	ccb = (struct cac_ccb *)sc->sc_ccbs;

	for (i = 0; i < CAC_MAX_CCBS; i++, ccb++) {
		/* Create the DMA map for this CCB's data */
		error = bus_dmamap_create(sc->sc_dmat, CAC_MAX_XFER,
		    CAC_SG_SIZE, CAC_MAX_XFER, 0,
		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
		    &ccb->ccb_dmamap_xfer);

		if (error) {
			printf("%s: can't create ccb dmamap (%d)\n",
			    sc->sc_dv.dv_xname, error);
			break;
		}

		ccb->ccb_paddr = sc->sc_ccbs_paddr + i * sizeof(struct cac_ccb);
		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_chain);
	}

	/* Start firmware background tasks, if needed. */
	if (startfw) {
		if (cac_cmd(sc, CAC_CMD_START_FIRMWARE, &cinfo, sizeof(cinfo),
		    0, 0, CAC_CCB_DATA_IN, NULL)) {
			printf("%s: CAC_CMD_START_FIRMWARE failed\n",
			    sc->sc_dv.dv_xname);
			return (-1);
		}
	}

	if (cac_cmd(sc, CAC_CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo), 0, 0,
	    CAC_CCB_DATA_IN, NULL)) {
		printf("%s: CAC_CMD_GET_CTRL_INFO failed\n",
		    sc->sc_dv.dv_xname);
		return (-1);
	}

	if (!cinfo.num_drvs) {
		printf("%s: no volumes defined\n", sc->sc_dv.dv_xname);
		return (-1);
	}

	sc->sc_nunits = cinfo.num_drvs;
	sc->sc_dinfos = malloc(cinfo.num_drvs * sizeof(struct cac_drive_info),
	    M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc_dinfos == NULL) {
		printf("%s: cannot allocate memory for drive_info\n",
		    sc->sc_dv.dv_xname);
		return (-1);
	}

	sc->sc_link.adapter_softc = sc;
	sc->sc_link.adapter = &cac_switch;
	sc->sc_link.adapter_target = cinfo.num_drvs;
	sc->sc_link.adapter_buswidth = cinfo.num_drvs;
	sc->sc_link.openings = CAC_MAX_CCBS / sc->sc_nunits;
	if (sc->sc_link.openings < 4 )
		sc->sc_link.openings = 4;

	bzero(&saa, sizeof(saa));
	saa.saa_sc_link = &sc->sc_link;

	config_found(&sc->sc_dv, &saa, scsiprint);

	/* Set our `shutdownhook' before we start any device activity. */
	if (cac_sdh == NULL)
		cac_sdh = shutdownhook_establish(cac_shutdown, NULL);

	(*sc->sc_cl->cl_intr_enable)(sc, 1);

#if NBIO > 0
	if (bio_register(&sc->sc_dv, cac_ioctl) != 0)
		printf("%s: controller registration failed\n",
		    sc->sc_dv.dv_xname);
	else
		sc->sc_ioctl = cac_ioctl;

#ifndef SMALL_KERNEL
	if (cac_create_sensors(sc) != 0)
		printf("%s: unable to create sensors\n", sc->sc_dv.dv_xname);
#endif
#endif


	return (0);
}