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; } }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }