int astattach(struct ata_device *atadev) { struct ast_softc *stp; struct ast_readposition position; dev_t dev; stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO); if (!stp) { ata_prtdev(atadev, "out of memory\n"); return 0; } stp->device = atadev; stp->lun = ata_get_lun(&ast_lun_map); ata_set_name(atadev, "ast", stp->lun); bufq_init(&stp->queue); if (ast_sense(stp)) { free(stp, M_AST); return 0; } if (!strcmp(atadev->param->model, "OnStream DI-30")) { struct ast_transferpage transfer; struct ast_identifypage identify; stp->flags |= F_ONSTREAM; bzero(&transfer, sizeof(struct ast_transferpage)); ast_mode_sense(stp, ATAPI_TAPE_TRANSFER_PAGE, &transfer, sizeof(transfer)); bzero(&identify, sizeof(struct ast_identifypage)); ast_mode_sense(stp, ATAPI_TAPE_IDENTIFY_PAGE, &identify, sizeof(identify)); strncpy(identify.ident, "FBSD", 4); ast_mode_select(stp, &identify, sizeof(identify)); ast_read_position(stp, 0, &position); } devstat_add_entry(&stp->stats, "ast", stp->lun, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_SEQUENTIAL | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_TAPE); dev = make_dev(&ast_cdevsw, dkmakeminor(stp->lun, 0, 0), UID_ROOT, GID_OPERATOR, 0640, "ast%d", stp->lun); dev->si_drv1 = stp; dev->si_iosize_max = 256 * DEV_BSIZE; stp->dev1 = dev; dev = make_dev(&ast_cdevsw, dkmakeminor(stp->lun, 0, 1), UID_ROOT, GID_OPERATOR, 0640, "nast%d", stp->lun); dev->si_drv1 = stp; dev->si_iosize_max = 256 * DEV_BSIZE; stp->dev2 = dev; stp->device->flags |= ATA_D_MEDIA_CHANGED; ast_describe(stp); atadev->driver = stp; return 1; }
int afdattach(struct ata_device *atadev) { struct afd_softc *fdp; dev_t dev; fdp = malloc(sizeof(struct afd_softc), M_AFD, M_NOWAIT | M_ZERO); if (!fdp) { ata_prtdev(atadev, "out of memory\n"); return 0; } fdp->device = atadev; fdp->lun = ata_get_lun(&afd_lun_map); ata_set_name(atadev, "afd", fdp->lun); bufq_init(&fdp->queue); if (afd_sense(fdp)) { free(fdp, M_AFD); return 0; } devstat_add_entry(&fdp->stats, "afd", fdp->lun, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, DEVSTAT_PRIORITY_WFD); dev = disk_create(fdp->lun, &fdp->disk, 0, &afd_cdevsw, &afddisk_cdevsw); dev->si_drv1 = fdp; fdp->dev = dev; if (!strncmp(atadev->param->model, "IOMEGA ZIP", 10) || !strncmp(atadev->param->model, "IOMEGA Clik!", 12)) fdp->dev->si_iosize_max = 64 * DEV_BSIZE; else fdp->dev->si_iosize_max = 252 * DEV_BSIZE; afd_describe(fdp); atadev->flags |= ATA_D_MEDIA_CHANGED; atadev->driver = fdp; return 1; }
int wstattach(struct atapi *ata, int unit, struct atapi_params *ap, int debug) { struct wst *t; int lun; if (wstnlun >= NUNIT) { printf("wst: too many units\n"); return(-1); } if (!atapi_request_immediate) { printf("wst: configuration error, ATAPI core code not present!\n"); printf( "wst: check `options ATAPI_STATIC' in your kernel config file!\n"); return(-1); } t = malloc(sizeof(struct wst), M_TEMP, M_NOWAIT); if (!t) { printf("wst: out of memory\n"); return(-1); } wsttab[wstnlun] = t; bzero(t, sizeof(struct wst)); bufq_init(&t->buf_queue); t->ata = ata; t->unit = unit; t->ata->use_dsc = 1; lun = t->lun = wstnlun; t->param = ap; t->flags = WST_MEDIA_CHANGED | WST_DEBUG; if (wst_sense(t)) return -1; wst_describe(t); wstnlun++; make_dev(&wst_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0640, "rwst%d", t->lun); return(1); }
STATIC sscop_t * sscop_alloc_priv(queue_t *q) { sscop_t *sp; if ((sp = kmem_cache_alloc(sscop_cachep))) { bzero(sp, sizeof(*sp)); RD(q)->q_ptr = WR(q)->q_tpr = sp; sp->rq = RD(q); sp->wq = WR(q); /* link into master list */ if ((sp->next = sscop_priv_list)) sp->next->pprev = &sp->next; sp->pprev = &sscop_priv_list; sscop_priv_list = sp; sp->t_state = TS_UNINIT; sp->n_ostr = sscop_default_o_streams; sp->n_istr = sscop_default_i_streams; sp->a_rwnd = sscop_default_rmem; bufq_init(&sp->out_of_order_queue); bufq_init(&sp->duplicate_queue); bufq_init(&sp->write_queue); bufq_init(&sp->urgent_queue); bufq_init(&sp->retrans_queue); bufq_init(&sp->error_queue); bufq_init(&sp->connect_queue); sp->pmtu = 576; sp->max_retrans = sscop_assoc_max_retrans; sp->max_inits = sscop_max_init_retries; } return (sp); }
/* ARGSUSED */ int mfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { struct vnode *devvp; struct mfs_args args; struct ufsmount *ump; struct fs *fs; struct mfsnode *mfsp; char fspec[MNAMELEN]; int flags, error; error = copyin(data, &args, sizeof(struct mfs_args)); if (error) return (error); /* * If updating, check whether changing from read-only to * read/write; if there is no device name, that's all we do. */ if (mp->mnt_flag & MNT_UPDATE) { ump = VFSTOUFS(mp); fs = ump->um_fs; if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; error = ffs_flushfiles(mp, flags, p); if (error) return (error); } if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) fs->fs_ronly = 0; #ifdef EXPORTMFS if (args.fspec == NULL) return (vfs_export(mp, &ump->um_export, &args.export_info)); #endif return (0); } error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL); if (error) return (error); error = getnewvnode(VT_MFS, NULL, &mfs_vops, &devvp); if (error) return (error); devvp->v_type = VBLK; if (checkalias(devvp, makedev(255, mfs_minor), NULL)) panic("mfs_mount: dup dev"); mfs_minor++; mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK | M_ZERO); devvp->v_data = mfsp; mfsp->mfs_baseoff = args.base; mfsp->mfs_size = args.size; mfsp->mfs_vnode = devvp; mfsp->mfs_pid = p->p_pid; bufq_init(&mfsp->mfs_bufq, BUFQ_FIFO); if ((error = ffs_mountfs(devvp, mp, p)) != 0) { mfsp->mfs_shutdown = 1; vrele(devvp); return (error); } ump = VFSTOUFS(mp); fs = ump->um_fs; memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt)); strlcpy(fs->fs_fsmnt, path, sizeof(fs->fs_fsmnt)); memcpy(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN); memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN); memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN); strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN); memcpy(&mp->mnt_stat.mount_info.mfs_args, &args, sizeof(args)); return (0); }
/* * The routine called by the low level scsi routine when it discovers * a device suitable for this driver. */ void sdattach(struct device *parent, struct device *self, void *aux) { struct sd_softc *sc = (struct sd_softc *)self; struct scsi_attach_args *sa = aux; struct disk_parms *dp = &sc->params; struct scsi_link *sc_link = sa->sa_sc_link; int sd_autoconf = scsi_autoconf | SCSI_SILENT | SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE; struct dk_cache dkc; int error, result; SC_DEBUG(sc_link, SDEV_DB2, ("sdattach:\n")); /* * Store information needed to contact our base driver */ sc->sc_link = sc_link; sc_link->interpret_sense = sd_interpret_sense; sc_link->device_softc = sc; if ((sc_link->flags & SDEV_ATAPI) && (sc_link->flags & SDEV_REMOVABLE)) sc_link->quirks |= SDEV_NOSYNCCACHE; if (!(sc_link->inqdata.flags & SID_RelAdr)) sc_link->quirks |= SDEV_ONLYBIG; /* * Note if this device is ancient. This is used in sdminphys(). */ if (!(sc_link->flags & SDEV_ATAPI) && SCSISPC(sa->sa_inqbuf->version) == 0) sc->flags |= SDF_ANCIENT; /* * Use the subdriver to request information regarding * the drive. We cannot use interrupts yet, so the * request must specify this. */ printf("\n"); scsi_xsh_set(&sc->sc_xsh, sc_link, sdstart); timeout_set(&sc->sc_timeout, (void (*)(void *))scsi_xsh_add, &sc->sc_xsh); /* Spin up non-UMASS devices ready or not. */ if ((sc->sc_link->flags & SDEV_UMASS) == 0) scsi_start(sc_link, SSS_START, sd_autoconf); /* * Some devices (e.g. Blackberry Pearl) won't admit they have * media loaded unless its been locked in. */ if ((sc_link->flags & SDEV_REMOVABLE) != 0) scsi_prevent(sc_link, PR_PREVENT, sd_autoconf); /* Check that it is still responding and ok. */ error = scsi_test_unit_ready(sc->sc_link, TEST_READY_RETRIES * 3, sd_autoconf); if (error) result = SDGP_RESULT_OFFLINE; else result = sd_get_parms(sc, &sc->params, sd_autoconf); if ((sc_link->flags & SDEV_REMOVABLE) != 0) scsi_prevent(sc_link, PR_ALLOW, sd_autoconf); switch (result) { case SDGP_RESULT_OK: printf("%s: %lluMB, %lu bytes/sector, %llu sectors", sc->sc_dev.dv_xname, dp->disksize / (1048576 / dp->secsize), dp->secsize, dp->disksize); printf("\n"); break; case SDGP_RESULT_OFFLINE: break; #ifdef DIAGNOSTIC default: panic("sdattach: unknown result (%#x) from get_parms", result); break; #endif } /* * Initialize disk structures. */ sc->sc_dk.dk_name = sc->sc_dev.dv_xname; bufq_init(&sc->sc_bufq, BUFQ_FIFO); /* * Enable write cache by default. */ memset(&dkc, 0, sizeof(dkc)); if (sd_ioctl_cache(sc, DIOCGCACHE, &dkc) == 0 && dkc.wrcache == 0) { dkc.wrcache = 1; sd_ioctl_cache(sc, DIOCSCACHE, &dkc); } /* * Establish a shutdown hook so that we can ensure that * our data has actually made it onto the platter at * shutdown time. Note that this relies on the fact * that the shutdown hook code puts us at the head of * the list (thus guaranteeing that our hook runs before * our ancestors'). */ if ((sc->sc_sdhook = shutdownhook_establish(sd_shutdown, sc)) == NULL) printf("%s: WARNING: unable to establish shutdown hook\n", sc->sc_dev.dv_xname); /* Attach disk. */ disk_attach(&sc->sc_dev, &sc->sc_dk); }
void wdattach(struct device *parent, struct device *self, void *aux) { struct wd_softc *wd = (void *)self; struct ata_atapi_attach *aa_link= aux; struct wdc_command wdc_c; int i, blank; char buf[41], c, *p, *q; WDCDEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE); wd->openings = aa_link->aa_openings; wd->drvp = aa_link->aa_drv_data; strlcpy(wd->drvp->drive_name, wd->sc_dev.dv_xname, sizeof(wd->drvp->drive_name)); wd->drvp->cf_flags = wd->sc_dev.dv_cfdata->cf_flags; if ((NERRS_MAX - 2) > 0) wd->drvp->n_dmaerrs = NERRS_MAX - 2; else wd->drvp->n_dmaerrs = 0; /* read our drive info */ if (wd_get_params(wd, at_poll, &wd->sc_params) != 0) { printf("%s: IDENTIFY failed\n", wd->sc_dev.dv_xname); return; } for (blank = 0, p = wd->sc_params.atap_model, q = buf, i = 0; i < sizeof(wd->sc_params.atap_model); i++) { c = *p++; if (c == '\0') break; if (c != ' ') { if (blank) { *q++ = ' '; blank = 0; } *q++ = c; } else blank = 1; } *q++ = '\0'; printf(": <%s>\n", buf); wdc_probe_caps(wd->drvp, &wd->sc_params); wdc_print_caps(wd->drvp); if ((wd->sc_params.atap_multi & 0xff) > 1) { wd->sc_multi = wd->sc_params.atap_multi & 0xff; } else { wd->sc_multi = 1; } printf("%s: %d-sector PIO,", wd->sc_dev.dv_xname, wd->sc_multi); /* use 48-bit LBA if enabled */ /* XXX: shall we use it if drive capacity < 137Gb? */ if ((wd->sc_params.atap_cmd2_en & ATAPI_CMD2_48AD) != 0) wd->sc_flags |= WDF_LBA48; /* Prior to ATA-4, LBA was optional. */ if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0) wd->sc_flags |= WDF_LBA; #if 0 /* ATA-4 requires LBA. */ if (wd->sc_params.atap_ataversion != 0xffff && wd->sc_params.atap_ataversion >= WDC_VER_ATA4) wd->sc_flags |= WDF_LBA; #endif if ((wd->sc_flags & WDF_LBA48) != 0) { wd->sc_capacity = (((u_int64_t)wd->sc_params.atap_max_lba[3] << 48) | ((u_int64_t)wd->sc_params.atap_max_lba[2] << 32) | ((u_int64_t)wd->sc_params.atap_max_lba[1] << 16) | (u_int64_t)wd->sc_params.atap_max_lba[0]); printf(" LBA48, %lluMB, %llu sectors\n", wd->sc_capacity / (1048576 / DEV_BSIZE), wd->sc_capacity); } else if ((wd->sc_flags & WDF_LBA) != 0) { wd->sc_capacity = (wd->sc_params.atap_capacity[1] << 16) | wd->sc_params.atap_capacity[0]; printf(" LBA, %lluMB, %llu sectors\n", wd->sc_capacity / (1048576 / DEV_BSIZE), wd->sc_capacity); } else { wd->sc_capacity = wd->sc_params.atap_cylinders * wd->sc_params.atap_heads * wd->sc_params.atap_sectors; printf(" CHS, %lluMB, %d cyl, %d head, %d sec, %llu sectors\n", wd->sc_capacity / (1048576 / DEV_BSIZE), wd->sc_params.atap_cylinders, wd->sc_params.atap_heads, wd->sc_params.atap_sectors, wd->sc_capacity); } WDCDEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n", self->dv_xname, wd->sc_params.atap_dmatiming_mimi, wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE); /* use read look ahead if supported */ if (wd->sc_params.atap_cmd_set1 & WDC_CMD1_AHEAD) { bzero(&wdc_c, sizeof(struct wdc_command)); wdc_c.r_command = SET_FEATURES; wdc_c.r_precomp = WDSF_READAHEAD_EN; wdc_c.timeout = 1000; wdc_c.flags = at_poll; if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { printf("%s: enable look ahead command didn't " "complete\n", wd->sc_dev.dv_xname); } } /* use write cache if supported */ if (wd->sc_params.atap_cmd_set1 & WDC_CMD1_CACHE) { bzero(&wdc_c, sizeof(struct wdc_command)); wdc_c.r_command = SET_FEATURES; wdc_c.r_precomp = WDSF_EN_WR_CACHE; wdc_c.timeout = 1000; wdc_c.flags = at_poll; if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { printf("%s: enable write cache command didn't " "complete\n", wd->sc_dev.dv_xname); } } /* * FREEZE LOCK the drive so malicous users can't lock it on us. * As there is no harm in issuing this to drives that don't * support the security feature set we just send it, and don't * bother checking if the drive sends a command abort to tell us it * doesn't support it. */ bzero(&wdc_c, sizeof(struct wdc_command)); wdc_c.r_command = WDCC_SEC_FREEZE_LOCK; wdc_c.timeout = 1000; wdc_c.flags = at_poll; if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { printf("%s: freeze lock command didn't complete\n", wd->sc_dev.dv_xname); } /* * Initialize disk structures. */ wd->sc_dk.dk_name = wd->sc_dev.dv_xname; bufq_init(&wd->sc_bufq, BUFQ_DEFAULT); timeout_set(&wd->sc_restart_timeout, wdrestart, wd); /* Attach disk. */ disk_attach(&wd->sc_dev, &wd->sc_dk); wd->sc_wdc_bio.lp = wd->sc_dk.dk_label; }
static cam_status ptctor(struct cam_periph *periph, void *arg) { struct pt_softc *softc; struct ccb_setasync csa; struct ccb_getdev *cgd; cgd = (struct ccb_getdev *)arg; if (periph == NULL) { printf("ptregister: periph was NULL!!\n"); return(CAM_REQ_CMP_ERR); } if (cgd == NULL) { printf("ptregister: no getdev CCB, can't register device\n"); return(CAM_REQ_CMP_ERR); } softc = (struct pt_softc *)malloc(sizeof(*softc),M_DEVBUF,M_NOWAIT); if (softc == NULL) { printf("daregister: Unable to probe new device. " "Unable to allocate softc\n"); return(CAM_REQ_CMP_ERR); } bzero(softc, sizeof(*softc)); LIST_INIT(&softc->pending_ccbs); softc->state = PT_STATE_NORMAL; bufq_init(&softc->buf_queue); softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000; periph->softc = softc; cam_extend_set(ptperiphs, periph->unit_number, periph); devstat_add_entry(&softc->device_stats, "pt", periph->unit_number, 0, DEVSTAT_NO_BLOCKSIZE, SID_TYPE(&cgd->inq_data) | DEVSTAT_TYPE_IF_SCSI, DEVSTAT_PRIORITY_OTHER); softc->dev = make_dev(&pt_cdevsw, periph->unit_number, UID_ROOT, GID_OPERATOR, 0600, "%s%d", periph->periph_name, periph->unit_number); /* * Add async callbacks for bus reset and * bus device reset calls. I don't bother * checking if this fails as, in most cases, * the system will function just fine without * them and the only alternative would be to * not attach the device on failure. */ xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5); csa.ccb_h.func_code = XPT_SASYNC_CB; csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE; csa.callback = ptasync; csa.callback_arg = periph; xpt_action((union ccb *)&csa); /* Tell the user we've attached to the device */ xpt_announce_periph(periph, NULL); return(CAM_REQ_CMP); }
/* * Controller is working, and drive responded. Attach it. */ void fdattach(struct device *parent, struct device *self, void *aux) { struct fdc_softc *fdc = (void *)parent; struct fd_softc *fd = (void *)self; struct fdc_attach_args *fa = aux; struct fd_type *type = fa->fa_deftype; int drive = fa->fa_drive; if (!type || (fa->fa_flags & 0x10)) { /* The config has overridden this. */ switch (fa->fa_flags & 0x07) { case 1: /* 2.88MB */ type = &fd_types[7]; break; case 2: /* 1.44MB */ type = &fd_types[0]; break; case 3: /* 1.2MB */ type = &fd_types[1]; break; case 4: /* 720K */ type = &fd_types[4]; break; case 5: /* 360K */ type = &fd_types[3]; break; case 6: /* 1.2 MB japanese format */ type = &fd_types[8]; break; #ifdef __alpha__ default: /* 1.44MB, how to detect others? * idea from NetBSD -- [email protected] */ type = &fd_types[0]; #endif } } if (type) printf(": %s %d cyl, %d head, %d sec\n", type->name, type->tracks, type->heads, type->sectrac); else printf(": density unknown\n"); fd->sc_cylin = -1; fd->sc_drive = drive; fd->sc_deftype = type; fdc->sc_type[drive] = FDC_TYPE_DISK; fdc->sc_link.fdlink.sc_fd[drive] = fd; /* * Initialize and attach the disk structure. */ fd->sc_dk.dk_flags = DKF_NOLABELREAD; fd->sc_dk.dk_name = fd->sc_dev.dv_xname; bufq_init(&fd->sc_bufq, BUFQ_DEFAULT); disk_attach(&fd->sc_dev, &fd->sc_dk); /* Setup timeout structures */ timeout_set(&fd->fd_motor_on_to, fd_motor_on, fd); timeout_set(&fd->fd_motor_off_to, fd_motor_off, fd); timeout_set(&fd->fdtimeout_to, fdtimeout, fd); }