devstat_remove_entry(&softc->device_stats);
cam_extend_release(chperiphs, periph->unit_number);
xpt_print(periph->path, "removing device entry\n");
- dev_ops_remove(&ch_ops, -1, periph->unit_number);
+ dev_ops_remove_minor(&ch_ops, periph->unit_number);
kfree(softc, M_DEVBUF);
}
strncpy(label->d_packname, cgd.inq_data.product,
min(SID_PRODUCT_SIZE, sizeof(label->d_packname)));
#endif
-
+#if 0
/*
* Mandatory fields
*/
info.d_secpercyl = softc->params.heads *
softc->params.secs_per_track;
disk_setdiskinfo(&softc->disk, &info);
-
+#endif
/*
* Check to see whether or not the blocksize is set yet.
* If it isn't, set it and then clear the blocksize
struct da_softc *softc;
struct ccb_pathinq cpi;
struct ccb_getdev *cgd;
+#if 0
+ struct disk_info info;
+#endif
char tmpstr[80];
caddr_t match;
/*
* Register this media as a disk
*/
-
CAM_SIM_UNLOCK(periph->sim);
disk_create(periph->unit_number, &softc->disk, &da_ops);
softc->disk.d_rawdev->si_iosize_max = MAXPHYS;
(DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL,
dasendorderedtag, softc);
+#if 0
+ /*
+ * Set diskinfo. It should be ok here as we already did a DA_CCB_PROBE.
+ * Setting this info will also trigger probing of the device.
+ */
+ CAM_SIM_UNLOCK(periph->sim);
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = softc->params.secsize;
+ info.d_media_blocks = softc->params.sectors;
+ info.d_media_size = 0;
+ info.d_secpertrack = softc->params.secs_per_track;
+ info.d_nheads = softc->params.heads;
+ info.d_ncylinders = softc->params.cylinders;
+ info.d_secpercyl = softc->params.heads *
+ softc->params.secs_per_track;
+ disk_setdiskinfo(&softc->disk, &info);
+
+ CAM_SIM_LOCK(periph->sim);
+#endif
+
return(CAM_REQ_CMP);
}
{
struct da_softc *softc;
struct ccb_scsiio *csio;
+ struct disk_info info;
softc = (struct da_softc *)periph->softc;
csio = &done_ccb->csio;
(uintmax_t)dp->sectors,
dp->secsize, dp->heads, dp->secs_per_track,
dp->cylinders);
+ CAM_SIM_UNLOCK(periph->sim);
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = softc->params.secsize;
+ info.d_media_blocks = softc->params.sectors;
+ info.d_media_size = 0;
+ info.d_secpertrack = softc->params.secs_per_track;
+ info.d_nheads = softc->params.heads;
+ info.d_ncylinders = softc->params.cylinders;
+ info.d_secpercyl = softc->params.heads *
+ softc->params.secs_per_track;
+ disk_setdiskinfo(&softc->disk, &info);
+ CAM_SIM_LOCK(periph->sim);
} else {
int error;
if (bootverbose) {
xpt_print(periph->path, "removing device entry\n");
}
- dev_ops_remove(&pass_ops, -1, periph->unit_number);
+ dev_ops_remove_minor(&pass_ops, periph->unit_number);
kfree(softc, M_DEVBUF);
}
cam_extend_release(ptperiphs, periph->unit_number);
xpt_print(periph->path, "removing device entry\n");
- dev_ops_remove(&pt_ops, -1, periph->unit_number);
+ dev_ops_remove_minor(&pt_ops, periph->unit_number);
kfree(softc, M_DEVBUF);
}
cam_extend_release(saperiphs, periph->unit_number);
xpt_print(periph->path, "removing device entry\n");
- dev_ops_remove(&sa_ops, SA_UNITMASK, SA_UNIT(periph->unit_number));
+ kprintf("devfs: PLEASE check that only the right scsi sa devices were removed!!!!\n");
+ dev_ops_remove_minor(&sa_ops, /*SA_UNITMASK,*/ SA_UNIT(periph->unit_number));
kfree(softc, M_SCSISA);
}
cam_extend_release(sesperiphs, periph->unit_number);
xpt_print(periph->path, "removing device entry\n");
- dev_ops_remove(&ses_ops, -1, periph->unit_number);
+ dev_ops_remove_minor(&ses_ops, periph->unit_number);
kfree(softc, M_SCSISES);
}
int unit;
unit = device_get_unit(sc->fc->bdev);
- dev_ops_remove(&firewire_ops, FW_UNITMASK, FW_UNIT(unit));
+ kprintf("devfs: Please check that only the right firewire devices were removed!!!!\n");
+ dev_ops_remove_minor(&firewire_ops, /*FW_UNITMASK, */FW_UNIT(unit));
return(0);
}
int i;
release_dev(usb_dev);
- dev_ops_remove(&usb_ops, -1, USB_DEV_MINOR);
+ dev_ops_remove_minor(&usb_ops, USB_DEV_MINOR);
usb_dev = NULL;
for (i = 0; i < USB_NUM_TASKQS; i++) {
vfs/userfs/userfs_vnops.c optional userfs
vfs/userfs/userfs_inode.c optional userfs
vfs/userfs/userfs_elms.c optional userfs
+vfs/devfs/devfs_core.c standard
+vfs/devfs/devfs_vnops.c standard
+vfs/devfs/devfs_vfsops.c standard
+vfs/devfs/devfs_helper.c standard
+vfs/devfs/devfs_rules.c standard
vfs/hammer/hammer_blockmap.c optional hammer
vfs/hammer/hammer_btree.c optional hammer
vfs/hammer/hammer_cursor.c optional hammer
--- /dev/null
+# VKERNEL - configuration for a virtual kernel
+#
+# $DragonFly: src/sys/config/VKERNEL,v 1.14 2008/11/09 18:57:17 dillon Exp $
+
+platform vkernel # platform architecture (i386, vkernel, etc)
+machine i386
+machine_arch i386 # cpu architecture (i386, etc)
+ident VKERNEL
+maxusers 0
+
+makeoptions DEBUG=-g
+
+cpu I586_CPU
+cpu I686_CPU
+
+options DEBUG_PCTRACK
+
+options KTR
+options KTR_GIANT_CONTENTION
+options KTR_SPIN_CONTENTION
+#options DEBUG_CRIT_SECTIONS
+
+options QUOTA
+options DUMMYNET
+options IPFIREWALL #firewall
+options IPFIREWALL_FORWARD #enable transparent proxy support
+options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default
+
+# ALTQ
+options ALTQ #alternate queueing
+options ALTQ_CBQ #class based queueing
+options ALTQ_RED #random early detection
+options ALTQ_RIO #triple red for diffserv (needs RED)
+options ALTQ_HFSC #hierarchical fair service curve
+options ALTQ_PRIQ #priority queue
+options ALTQ_FAIRQ #fair queue
+#options ALTQ_NOPCC #don't use processor cycle counter
+options ALTQ_DEBUG #for debugging
+
+options IPSEC #IP security
+options IPSEC_ESP #IP security (crypto; define w/ IPSEC)
+options IPSEC_DEBUG #debug for IP security
+
+options DEVFS
+options HAMMER
+options EXT2FS
+options INET #InterNETworking
+options INET6 #IPv6 communications protocols
+options FFS #Berkeley Fast Filesystem
+options FFS_ROOT #FFS usable as root device [keep this!]
+options SOFTUPDATES #Enable FFS soft updates support
+options UFS_DIRHASH #Improve performance on big directories
+options MFS #Memory Filesystem
+options MD_ROOT #MD is a potential root device
+options NFS #Network Filesystem
+options NFS_ROOT #NFS usable as root device, NFS required
+options MSDOSFS #MSDOS Filesystem
+options CD9660 #ISO 9660 Filesystem
+options PROCFS #Process filesystem
+options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
+options COMPAT_DF12 #Compatible with DragonFly 1.2 and earlier
+options DEVICE_POLLING # Support mixed interrupt-polling
+ # handling of network device drivers
+options UCONSOLE #Allow users to grab the console
+options KTRACE #ktrace(1) support
+options SYSVSHM #SYSV-style shared memory
+options SYSVMSG #SYSV-style message queues
+options SYSVSEM #SYSV-style semaphores
+options P1003_1B #Posix P1003_1B real-time extensions
+options _KPOSIX_PRIORITY_SCHEDULING
+options ICMP_BANDLIM #Rate limit bad replies
+
+options SMP # Symmetric MultiProcessor Kernel
+
+# Debugging for Development
+options DDB
+options DDB_TRACE
+options INVARIANTS
+
+#options CARP
+
+# Floating point support - do not disable.
+device npx0 at nexus?
+
+# Pseudo devices - the number indicates how many units to allocate.
+pseudo-device loop # Network loopback
+pseudo-device ether # Ethernet support
+pseudo-device sl 1 # Kernel SLIP
+pseudo-device ppp 1 # Kernel PPP
+pseudo-device tun # Packet tunnel.
+pseudo-device pty # Pseudo-ttys (telnet etc)
+pseudo-device md # Memory "disks"
+pseudo-device gif # IPv6 and IPv4 tunneling
+pseudo-device faith 1 # IPv6-to-IPv4 relaying (translation)
+
+#pseudo-device carp
+
+# The `bpf' pseudo-device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+pseudo-device bpf #Berkeley packet filter
+
+# VIRTUAL DEVICES
+#
+device vn
+device vkd
+device vke
+
+device vcd
break;
case MOD_UNLOAD :
- dev_ops_remove(&ipl_ops, 0, 0);
+ dev_ops_remove_all(&ipl_ops);
error = ipldetach();
break;
default:
void
agp_free_cdev(device_t dev)
{
- dev_ops_remove(&agp_ops, -1, device_get_unit(dev));
+ dev_ops_remove_minor(&agp_ops, device_get_unit(dev));
}
void
/*-
- * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
static void
ar_attach_raid(struct ar_softc *rdp, int update)
{
+ struct disk_info info;
cdev_t dev;
int disk;
dev->si_iosize_max = 256 * DEV_BSIZE;
rdp->dev = dev;
+ /*
+ * Set disk info, as it appears that all needed data is available already.
+ * Setting the disk info will also cause the probing to start.
+ */
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = DEV_BSIZE; /* mandatory */
+ info.d_media_blocks = rdp->total_sectors;
+
+ info.d_secpertrack = rdp->sectors; /* optional */
+ info.d_nheads = rdp->heads;
+ info.d_ncylinders = rdp->cylinders;
+ info.d_secpercyl = rdp->sectors * rdp->heads;
+
kprintf("ar%d: %lluMB <ATA ", rdp->lun, (unsigned long long)
(rdp->total_sectors / ((1024L * 1024L) / DEV_BSIZE)));
switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
else
kprintf(" %d INVALID no RAID config info on this disk\n", disk);
}
+ disk_setdiskinfo(&rdp->disk, &info);
}
int
static int
aropen(struct dev_open_args *ap)
{
+#if 0
struct ar_softc *rdp = ap->a_head.a_dev->si_drv1;
struct disk_info info;
info.d_secpercyl = rdp->sectors * rdp->heads;
disk_setdiskinfo(&rdp->disk, &info);
return 0;
+#endif
}
static int
biodone(bio);
}
devstat_remove_entry(&stp->stats);
- dev_ops_remove(&ast_ops, dkunitmask(), dkmakeunit(stp->lun));
+ kprintf("devfs: Please check that only the right atapi-tape device was removed!!\n");
+ dev_ops_remove_minor(&ast_ops,/* dkunitmask(), */dkmakeunit(stp->lun));
ata_free_name(atadev);
ata_free_lun(&ast_lun_map, stp->lun);
kfree(stp, M_AST);
struct fd_data *fd;
fd = device_get_softc(dev);
- dev_ops_remove(&fd_ops,
- dkunitmask() | dkmakeslice(-1) | dkmakepart(128|64),
+ kprintf("devfs: Please make sure that only the right fd device was removed!!!\n");
+ dev_ops_remove_minor(&fd_ops,
+ /*dkunitmask() | dkmakeslice(-1) | dkmakepart(128|64),*/
dkmakeminor(fd->fdu, WHOLE_DISK_SLICE, 128));
disk_invalidate(&fd->disk);
disk_destroy(&fd->disk);
mdcreate(void)
{
struct md_s *sc;
+ struct disk_info info;
MALLOC(sc, struct md_s *,sizeof(*sc), M_MD, M_WAITOK | M_ZERO);
sc->unit = mdunits++;
sc->dev->si_drv1 = sc;
sc->dev->si_iosize_max = DFLTPHYS;
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = DEV_BSIZE; /* mandatory */
+ info.d_media_blocks = sc->nsect;
+
+ info.d_secpertrack = 1024; /* optional */
+ info.d_nheads = 1;
+ info.d_secpercyl = info.d_secpertrack * info.d_nheads;
+ info.d_ncylinders = (u_int)(info.d_media_blocks / info.d_secpercyl);
+ disk_setdiskinfo(&sc->disk, &info);
+
return (sc);
}
case MOD_UNLOAD:
/* deregister controlling device */
destroy_dev(atacdev);
- dev_ops_remove(&ata_ops, 0, 0);
+ dev_ops_remove_all(&ata_ops);
return 0;
default:
ata_fail_requests(dev);
/* don't leave anything behind */
- dev_ops_remove(&acd_ops, dkunitmask(), dkmakeunit(device_get_unit(dev)));
+ kprintf("devfs: Please check that only the right ATA CD device was removed!!!\n");
+ dev_ops_remove_minor(&acd_ops, /*dkunitmask(), */dkmakeunit(device_get_unit(dev)));
disk_invalidate(&cdp->disk);
disk_destroy(&cdp->disk);
devstat_remove_entry(&cdp->stats);
ata_fail_requests(dev);
/* dont leave anything behind */
- dev_ops_remove(&ast_ops, dkunitmask(), dkmakeunit(device_get_unit(dev)));
+ kprintf("devfs: Please check that only the right ata tape device was removed!!!\n");
+ dev_ops_remove_minor(&ast_ops, /*dkunitmask(), */dkmakeunit(device_get_unit(dev)));
devstat_remove_entry(&stp->stats);
device_set_ivars(dev, NULL);
kfree(stp, M_AST);
}
kfree(vn, M_DEVBUF);
}
- dev_ops_remove(&vn_ops, 0, 0);
+ dev_ops_remove_all(&vn_ops);
break;
default:
break;
wakeup(sc);
DEBUG_printf(dev, "releasing resources\n");
cmx_release_resources(dev);
- dev_ops_remove(&cmx_ops, -1, device_get_unit(dev));
+ dev_ops_remove_minor(&cmx_ops, device_get_unit(dev));
return 0;
}
dev->si_drv1 = NULL;
}
}
- dev_ops_remove(&kbd_ops, -1, kbd->kb_index);
+ dev_ops_remove_minor(&kbd_ops, kbd->kb_index);
return 0;
}
BUS_TEARDOWN_INTR(device_get_parent(dev), dev, sc->sc_intr, sc->sc_ih);
bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr);
bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port);
- dev_ops_remove(&mse_ops, ~1, device_get_unit(dev) << 1);
+ dev_ops_remove_minor(&mse_ops, device_get_unit(dev) << 1);
return 0;
}
rid = 0;
BUS_TEARDOWN_INTR(device_get_parent(dev), dev, sc->intr, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, rid, sc->intr);
- dev_ops_remove(&psm_ops, PSM_MKMINOR(-1, 0), PSM_MKMINOR(unit, 0));
+ kprintf("devfs: Please make sure that only the right psm device was removed!!!!\n");
+ dev_ops_remove_minor(&psm_ops, /*PSM_MKMINOR(-1, 0), */PSM_MKMINOR(unit, 0));
return 0;
}
if (!LIST_EMPTY(&snp_sclist))
return (EBUSY);
ldisc_deregister(snooplinedisc);
- dev_ops_remove(&snp_ops, 0, 0);
+ dev_ops_remove_all(&snp_ops);
break;
default:
break;
video_info_t info;
int error;
+ KKASSERT(tp->t_dev);
+
scp = SC_STAT(tp->t_dev);
if (scp == NULL) /* tp == SC_MOUSE */
- return ENOIOCTL;
+ return ENOIOCTL;
adp = scp->sc->adp;
if (adp == NULL) /* shouldn't happen??? */
- return ENODEV;
+ return ENODEV;
switch (cmd) {
/*-
- * Copyright (c) 1992-1998 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
* All rights reserved.
*
* This code is derived from software contributed to The DragonFly Project
(SC_DEV((sc),(x))->si_tty) : NULL)
#define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN))
-static int debugger;
+static int debugger;
+static cdev_t cctl_dev;
/* prototypes */
static int scvidprobe(int unit, int flags, int cons);
*/
dev_ops_add(&sc_ops, ~(MAXCONS - 1), unit * MAXCONS);
- for (vc = 0; vc < sc->vtys; vc++) {
+ for (vc = 1; vc < sc->vtys; vc++) { //XXX: possibly breaks something, or even a lot
dev = make_dev(&sc_ops, vc + unit * MAXCONS,
UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc + unit * MAXCONS);
sc->dev[vc] = dev;
}
dev_ops_add(&sc_ops, -1, SC_CONSOLECTL); /* XXX */
- dev = make_dev(&sc_ops, SC_CONSOLECTL,
- UID_ROOT, GID_WHEEL, 0600, "consolectl");
- dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty);
- dev->si_drv1 = sc_console;
-
+ cctl_dev = make_dev(&sc_ops, SC_CONSOLECTL,
+ UID_ROOT, GID_WHEEL, 0600, "consolectl");
+ cctl_dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty);
+ cctl_dev->si_drv1 = sc_console;
return 0;
}
tp->t_oproc = scstart;
tp->t_param = scparam;
tp->t_stop = nottystop;
+
tp->t_dev = dev;
+
if (!ISTTYOPEN(tp)) {
ttychars(tp);
/* Use the current setting of the <-- key as default VERASE. */
(*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
ttyclose(tp);
crit_exit();
+
return(0);
}
static void
sccninit_fini(struct consdev *cp)
{
- cp->cn_dev = make_dev(&sc_ops, SC_CONSOLECTL,
- UID_ROOT, GID_WHEEL, 0600, "consolectl");
+ if (cctl_dev == NULL)
+ kprintf("sccninit_fini: WARNING: cctl_dev is NULL!\n");
+ cp->cn_dev = cctl_dev;
}
static void
} else {
/* assert(sc_malloc) */
sc->dev = kmalloc(sizeof(cdev_t)*sc->vtys, M_SYSCONS, M_WAITOK | M_ZERO);
+
sc->dev[0] = make_dev(&sc_ops, unit*MAXCONS, UID_ROOT,
GID_WHEEL, 0600, "ttyv%r", unit*MAXCONS);
+
sc->dev[0]->si_tty = ttymalloc(sc->dev[0]->si_tty);
scp = alloc_scp(sc, sc->first_vty);
sc->dev[0]->si_drv1 = scp;
bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
sc->aac_regs_rid, sc->aac_regs_resource);
}
- dev_ops_remove(&aac_ops, -1, device_get_unit(sc->aac_dev));
+ dev_ops_remove_minor(&aac_ops, device_get_unit(sc->aac_dev));
}
/*
{
cdev_t dev = ap->a_head.a_dev;
struct aac_disk *sc;
- struct disk_info info;
debug_called(0);
}
/* build synthetic label */
+#if 0
bzero(&info, sizeof(info));
info.d_media_blksize= AAC_BLOCK_SIZE; /* mandatory */
info.d_media_blocks = sc->ad_size;
info.d_secpercyl = sc->ad_sectors * sc->ad_heads;
disk_setdiskinfo(&sc->ad_disk, &info);
+#endif
sc->ad_flags |= AAC_DISK_OPEN;
return (0);
}
static int
aac_disk_attach(device_t dev)
{
+ struct disk_info info;
struct aac_disk *sc;
debug_called(0);
sc->ad_dev_t->si_iosize_max = aac_iosize_max;
sc->unit = device_get_unit(dev);
+ /*
+ * Set disk info, as it appears that all needed data is available already.
+ * Setting the disk info will also cause the probing to start.
+ */
+ bzero(&info, sizeof(info));
+ info.d_media_blksize= AAC_BLOCK_SIZE; /* mandatory */
+ info.d_media_blocks = sc->ad_size;
+
+ info.d_type = DTYPE_ESDI; /* optional */
+ info.d_secpertrack = sc->ad_sectors;
+ info.d_nheads = sc->ad_heads;
+ info.d_ncylinders = sc->ad_cylinders;
+ info.d_secpercyl = sc->ad_sectors * sc->ad_heads;
+
+ disk_setdiskinfo(&sc->ad_disk, &info);
+
return (0);
}
/* destroy control device */
if( sc->amr_dev_t != (cdev_t)NULL)
destroy_dev(sc->amr_dev_t);
- dev_ops_remove(&amr_ops, -1, device_get_unit(sc->amr_dev));
+ dev_ops_remove_minor(&amr_ops, device_get_unit(sc->amr_dev));
}
/*******************************************************************************
{
cdev_t dev = ap->a_head.a_dev;
struct amrd_softc *sc = (struct amrd_softc *)dev->si_drv1;
- struct disk_info info;
debug_called(1);
/* controller not active? */
if (sc->amrd_controller->amr_state & AMR_STATE_SHUTDOWN)
return(ENXIO);
-
+#if 0
bzero(&info, sizeof(info));
info.d_media_blksize = AMR_BLKSIZE; /* optional */
info.d_media_blocks = sc->amrd_drive->al_size;
info.d_secpercyl = sc->amrd_drive->al_sectors * sc->amrd_drive->al_heads;
disk_setdiskinfo(&sc->amrd_disk, &info);
-
+#endif
sc->amrd_flags |= AMRD_OPEN;
return (0);
}
static int
amrd_attach(device_t dev)
{
+ struct disk_info info;
struct amrd_softc *sc = (struct amrd_softc *)device_get_softc(dev);
device_t parent;
/* set maximum I/O size to match the maximum s/g size */
sc->amrd_dev_t->si_iosize_max = (AMR_NSEG - 1) * PAGE_SIZE;
+ /*
+ * Set disk info, as it appears that all needed data is available already.
+ * Setting the disk info will also cause the probing to start.
+ */
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = AMR_BLKSIZE; /* optional */
+ info.d_media_blocks = sc->amrd_drive->al_size;
+
+ info.d_type = DTYPE_SCSI; /* mandatory */
+ info.d_secpertrack = sc->amrd_drive->al_sectors;
+ info.d_nheads = sc->amrd_drive->al_heads;
+ info.d_ncylinders = sc->amrd_drive->al_cylinders;
+ info.d_secpercyl = sc->amrd_drive->al_sectors * sc->amrd_drive->al_heads;
+
+ disk_setdiskinfo(&sc->amrd_disk, &info);
+
return (0);
}
{
cdev_t dev = ap->a_head.a_dev;
struct idad_softc *drv;
- struct disk_info info;
drv = idad_getsoftc(dev);
if (drv == NULL)
return (ENXIO);
-
+#if 0
bzero(&info, sizeof(info));
info.d_media_blksize = drv->secsize; /* mandatory */
info.d_media_blocks = drv->secperunit;
info.d_secpercyl = drv->sectors * drv->heads;
disk_setdiskinfo(&drv->disk, &info);
-
+#endif
return (0);
}
idad_attach(device_t dev)
{
struct ida_drive_info dinfo;
+ struct disk_info info;
struct idad_softc *drv;
device_t parent;
cdev_t dsk;
dsk->si_drv1 = drv;
dsk->si_iosize_max = DFLTPHYS; /* XXX guess? */
+ /*
+ * Set disk info, as it appears that all needed data is available already.
+ * Setting the disk info will also cause the probing to start.
+ */
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = drv->secsize; /* mandatory */
+ info.d_media_blocks = drv->secperunit;
+
+ info.d_secpertrack = drv->sectors; /* optional */
+ info.d_type = DTYPE_SCSI;
+ info.d_nheads = drv->heads;
+ info.d_ncylinders = drv->cylinders;
+ info.d_secpercyl = drv->sectors * drv->heads;
+
+ disk_setdiskinfo(&drv->disk, &info);
+
return (0);
}
bus_dma_tag_destroy(sc->sg_dmatag);
if (sc->command_dmatag)
bus_dma_tag_destroy(sc->command_dmatag);
- dev_ops_remove(&ips_ops, -1, device_get_unit(sc->dev));
+ dev_ops_remove_minor(&ips_ops, device_get_unit(sc->dev));
return 0;
}
if (sc->mlx_enq2 != NULL)
kfree(sc->mlx_enq2, M_DEVBUF);
- dev_ops_remove(&mlx_ops, -1, device_get_unit(sc->mlx_dev));
+ dev_ops_remove_minor(&mlx_ops, device_get_unit(sc->mlx_dev));
}
/********************************************************************************
{
cdev_t dev = ap->a_head.a_dev;
struct mlxd_softc *sc = (struct mlxd_softc *)dev->si_drv1;
- struct disk_info info;
debug_called(1);
/* controller not active? */
if (sc->mlxd_controller->mlx_state & MLX_STATE_SHUTDOWN)
return(ENXIO);
-
+#if 0
bzero(&info, sizeof(info));
info.d_media_blksize= MLX_BLKSIZE; /* mandatory */
info.d_media_blocks = sc->mlxd_drive->ms_size;
info.d_secpercyl = sc->mlxd_drive->ms_sectors * sc->mlxd_drive->ms_heads;
disk_setdiskinfo(&sc->mlxd_disk, &info);
-
+#endif
sc->mlxd_flags |= MLXD_OPEN;
return (0);
}
mlxd_attach(device_t dev)
{
struct mlxd_softc *sc = (struct mlxd_softc *)device_get_softc(dev);
+ struct disk_info info;
device_t parent;
char *state;
cdev_t dsk;
s2 = (sc->mlxd_controller->mlx_enq2->me_max_sg - 1) * PAGE_SIZE;
dsk->si_iosize_max = imin(s1, s2);
+ /*
+ * Set disk info, as it appears that all needed data is available already.
+ * Setting the disk info will also cause the probing to start.
+ */
+ bzero(&info, sizeof(info));
+ info.d_media_blksize= MLX_BLKSIZE; /* mandatory */
+ info.d_media_blocks = sc->mlxd_drive->ms_size;
+
+ info.d_type = DTYPE_SCSI; /* optional */
+ info.d_secpertrack = sc->mlxd_drive->ms_sectors;
+ info.d_nheads = sc->mlxd_drive->ms_heads;
+ info.d_ncylinders = sc->mlxd_drive->ms_cylinders;
+ info.d_secpercyl = sc->mlxd_drive->ms_sectors * sc->mlxd_drive->ms_heads;
+
+ disk_setdiskinfo(&sc->mlxd_disk, &info);
+
return (0);
}
bus_release_resource(sc->twa_bus_dev, SYS_RES_IOPORT,
TWA_IO_CONFIG_REG, sc->twa_io_res);
- dev_ops_remove(&twa_ops, -1, device_get_unit(sc->twa_bus_dev));
+ dev_ops_remove_minor(&twa_ops, device_get_unit(sc->twa_bus_dev));
sysctl_ctx_free(&sc->twa_sysctl_ctx);
}
if (sc->twe_io != NULL)
bus_release_resource(sc->twe_dev, SYS_RES_IOPORT, TWE_IO_CONFIG_REG, sc->twe_io);
- dev_ops_remove(&twe_ops, -1, device_get_unit(sc->twe_dev));
+ dev_ops_remove_minor(&twe_ops, device_get_unit(sc->twe_dev));
/* destroy control device */
if (sc->twe_dev_t != (cdev_t)NULL)
destroy_dev(sc->twe_dev_t);
{
cdev_t dev = ap->a_head.a_dev;
struct twed_softc *sc = (struct twed_softc *)dev->si_drv1;
- struct disk_info info;
debug_called(4);
/* check that the controller is up and running */
if (sc->twed_controller->twe_state & TWE_STATE_SHUTDOWN)
return(ENXIO);
-
+#if 0
/* build disk info */
bzero(&info, sizeof(info));
info.d_media_blksize = TWE_BLOCK_SIZE; /* mandatory */
info.d_secpercyl = sc->twed_drive->td_sectors * sc->twed_drive->td_heads;
disk_setdiskinfo(&sc->twed_disk, &info);
-
+#endif
sc->twed_flags |= TWED_OPEN;
return (0);
}
twed_attach(device_t dev)
{
struct twed_softc *sc;
+ struct disk_info info;
device_t parent;
cdev_t dsk;
/* set the maximum I/O size to the theoretical maximum allowed by the S/G list size */
dsk->si_iosize_max = (TWE_MAX_SGL_LENGTH - 1) * PAGE_SIZE;
+ /*
+ * Set disk info, as it appears that all needed data is available already.
+ * Setting the disk info will also cause the probing to start.
+ */
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = TWE_BLOCK_SIZE; /* mandatory */
+ info.d_media_blocks = sc->twed_drive->td_size;
+
+ info.d_type = DTYPE_ESDI; /* optional */
+ info.d_secpertrack = sc->twed_drive->td_sectors;
+ info.d_nheads = sc->twed_drive->td_heads;
+ info.d_ncylinders = sc->twed_drive->td_cylinders;
+ info.d_secpercyl = sc->twed_drive->td_sectors * sc->twed_drive->td_heads;
+
+ disk_setdiskinfo(&sc->twed_disk, &info);
+
return (0);
}
kprintf("Disks registered: %d\n", disks_registered);
#if 0
if (--disks_registered == 0)
- dev_ops_remove(&tweddisk_ops);
+ dev_ops_remove_all(&tweddisk_ops);
#endif
#endif
}
}
#endif
- dev_ops_remove(&vinum_ops, 0, 0);
+ dev_ops_remove_all(&vinum_ops);
log(LOG_INFO, "vinum: unloaded\n"); /* tell the world */
return 0;
default:
* and dereference any ad-hoc-created devices, but does not
* dereference devices created via make_dev().
*/
- dev_ops_remove(&dgm_ops, DGM_UNITMASK, DGM_UNIT(sc->unit));
+ kprintf("devfs: Please check that only the right dgm devices were removed!!!!\n");
+ dev_ops_remove_minor(&dgm_ops/*, DGM_UNITMASK*/, DGM_UNIT(sc->unit));
callout_stop(&sc->toh);
}
if (ctlp->dev != NULL)
ctlp->dev = NULL;
- dev_ops_remove(&rp_ops, 0xffff0000, (unit + 1) << 16);
+ dev_ops_remove_minor(&rp_ops, /*0xffff0000, */(unit + 1) << 16);
}
int
#include <sys/rman.h>
#include <sys/timepps.h>
#include <sys/thread2.h>
+#include <vfs/devfs/devfs.h>
#include <machine/limits.h>
}
minorbase = UNIT_TO_MINOR(unit);
dev_ops_add(&sio_ops, UNIT_TO_MINOR(-1), minorbase);
+ //kprintf("sioattach: make_dev for ttyd%r\n", unit);
make_dev(&sio_ops, minorbase,
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
make_dev(&sio_ops, minorbase | CONTROL_INIT_STATE,
u_long oldcmd;
struct termios term;
#endif
-
mynor = minor(dev);
+
com = com_addr(MINOR_TO_UNIT(mynor));
if (com == NULL || com->gone)
return (ENODEV);
if (cp->cn_probegood) {
unit = (int)(intptr_t)cp->cn_private;
+ //kprintf("siocninit_fini: make_dev for ttyd%r\n", unit);
+ //if ((cp->cn_dev = devfs_find_device_by_name("ttyd%r", unit)) == NULL) {
cp->cn_dev = make_dev(&sio_ops, unit,
- UID_ROOT, GID_WHEEL, 0600,
- "ttyd%r", unit);
+ UID_ROOT, GID_WHEEL, 0600,
+ "ttyd%r", unit);
+ //}
}
}
pdev->si_drv1 = NULL;
release_dev(pdev);
unit = device_get_unit(dev);
- dev_ops_remove(&mixer_cdevsw, -1, PCMMKMINOR(unit, SND_DEV_CTL, 0));
+ dev_ops_remove_minor(&mixer_cdevsw, /*-1, */PCMMKMINOR(unit, SND_DEV_CTL, 0));
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
mixer_set(m, i, 0);
return EBUSY;
}
- dev_ops_remove(&sndstat_cdevsw, -1, SND_DEV_STATUS);
-
+ //dev_ops_remove(&sndstat_cdevsw, -1, SND_DEV_STATUS);
+ dev_ops_remove_all(&sndstat_cdevsw);
lockmgr(&sndstat_lock, LK_RELEASE);
return 0;
}
if (sce->dsp_devt) {
release_dev(sce->dsp_devt);
- dev_ops_remove(&dsp_cdevsw,
- PCMMKMINOR(-1, -1, 0),
+ kprintf("devfs: Please check that only the correct dsp devices were removed!!!\n");
+ dev_ops_remove_minor(&dsp_cdevsw,
+ /*PCMMKMINOR(-1, -1, 0),*/
PCMMKMINOR(unit, SND_DEV_DSP, sce->chan_num));
sce->dsp_devt = NULL;
}
if (sce->dspW_devt) {
release_dev(sce->dspW_devt);
- dev_ops_remove(&dsp_cdevsw,
- PCMMKMINOR(-1, -1, 0),
+ kprintf("devfs: Please check that only the correct dspW devices were removed!!!\n");
+ dev_ops_remove_minor(&dsp_cdevsw,
+ /*PCMMKMINOR(-1, -1, 0),*/
PCMMKMINOR(unit, SND_DEV_DSP16, sce->chan_num));
sce->dspW_devt = NULL;
}
}
if (sce->dspr_devt) {
release_dev(sce->dspr_devt);
- dev_ops_remove(&dsp_cdevsw,
- PCMMKMINOR(-1, -1, 0),
+ kprintf("devfs: Please check that only the correct dspr devices were removed!!!!\n");
+ dev_ops_remove_minor(&dsp_cdevsw,
+ /*PCMMKMINOR(-1, -1, 0),*/
PCMMKMINOR(unit, SND_DEV_DSPREC, sce->chan_num));
sce->dspr_devt = NULL;
}
crit_exit();
unit = device_get_unit(sc->sc_dev);
- dev_ops_remove(&ucom_ops, UCOMUNIT_MASK, unit);
+ kprintf("devfs: Please check that only the right ucom devices were removed!!!\n");
+ dev_ops_remove_minor(&ucom_ops, /*UCOMUNIT_MASK, */unit);
return (0);
}
/* destroy the device for the control endpoint */
ugen_destroy_devnodes(sc);
- dev_ops_remove(&ugen_ops,
- UGENUNITMASK, UGENMINOR(device_get_unit(sc->sc_dev), 0));
+ kprintf("devfs: Please check that only the right ugen devices were removed !!!\n");
+ dev_ops_remove_minor(&ugen_ops,
+ /*UGENUNITMASK,*/ UGENMINOR(device_get_unit(sc->sc_dev), 0));
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
return (0);
}
crit_exit();
}
- dev_ops_remove(&uhid_ops, -1, device_get_unit(self));
+ dev_ops_remove_minor(&uhid_ops, device_get_unit(self));
if (sc->sc_repdesc)
kfree(sc->sc_repdesc, M_USBDEV);
}
crit_exit();
- dev_ops_remove(&ulpt_ops, -1, device_get_unit(self));
+ dev_ops_remove_minor(&ulpt_ops, /*-1, */device_get_unit(self));
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
sc->sc_dev);
sc->state &= ~UMS_SELECT;
selwakeup(&sc->rsel);
}
- dev_ops_remove(&ums_ops, -1, device_get_unit(self));
+ dev_ops_remove_minor(&ums_ops, /*-1, */device_get_unit(self));
return 0;
}
urio_detach(device_t self)
{
DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
- dev_ops_remove(&urio_ops, -1, device_get_unit(self));
+ dev_ops_remove_minor(&urio_ops, /*-1, */device_get_unit(self));
/* XXX not implemented yet */
device_set_desc(self, NULL);
return 0;
crit_exit();
/* destroy the device for the control endpoint */
- dev_ops_remove(&uscanner_ops, -1, device_get_unit(sc->sc_dev));
+ dev_ops_remove_minor(&uscanner_ops, /*-1, */device_get_unit(sc->sc_dev));
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
sc->sc_dev);
/* then reload the main bktr driver module */
/* removing the ops automatically destroys all related devices */
- dev_ops_remove(&bktr_ops, 0x0f, device_get_unit(dev));
+ dev_ops_remove_minor(&bktr_ops, /*0x0f, */device_get_unit(dev));
/*
* Deallocate resources.
cxm_stop_hardware(sc);
/* Unregister the /dev/cxmN device. */
- dev_ops_remove(&cxm_ops, 0, device_get_unit(dev));
+ dev_ops_remove_minor(&cxm_ops, /*0, */device_get_unit(dev));
/*
* Deallocate scatter / gather list and buffers.
{
struct vkdisk_info *dsk;
struct vkd_softc *sc;
+ struct disk_info info;
struct stat st;
int i;
TAILQ_INIT(&sc->cotd_done);
sc->cotd = cothread_create(vkd_io_thread, vkd_io_intr, sc,
"vkd");
+
+ bzero(&info, sizeof(info));
+ info.d_media_blksize = DEV_BSIZE;
+ info.d_media_blocks = st.st_size / info.d_media_blksize;
+
+ info.d_nheads = 1;
+ info.d_ncylinders = 1;
+ info.d_secpertrack = info.d_media_blocks;
+ info.d_secpercyl = info.d_secpertrack * info.d_nheads;
+
+ disk_setdiskinfo(&sc->disk, &info);
}
}
if (fstat(sc->fd, &st) < 0 || st.st_size == 0)
return(ENXIO);
+/*
bzero(&info, sizeof(info));
info.d_media_blksize = DEV_BSIZE;
info.d_media_blocks = st.st_size / info.d_media_blksize;
info.d_secpertrack = info.d_media_blocks;
info.d_secpercyl = info.d_secpertrack * info.d_nheads;
- disk_setdiskinfo(&sc->disk, &info);
+ disk_setdiskinfo(&sc->disk, &info); */
return(0);
}
#include <sys/user.h>
#include <sys/copyright.h>
+int vfs_mountroot_devfs(void);
+
/* Components of the first process -- never freed. */
static struct session session0;
static struct pgrp pgrp0;
cache_copy(&mp->mnt_ncmountpt, &p->p_fd->fd_ncdir);
cache_copy(&mp->mnt_ncmountpt, &p->p_fd->fd_nrdir);
+ kprintf("Mounting devfs\n");
+ vfs_mountroot_devfs();
+
/*
* Need just enough stack to hold the faked-up "execve()" arguments.
*/
#include <sys/sysref2.h>
+#include <vfs/devfs/devfs.h>
+
+
static void cdev_terminate(struct cdev *dev);
MALLOC_DEFINE(M_DEVT, "cdev_t", "dev_t storage");
si->si_flags |= SI_HASHED | SI_ADHOC;
si->si_umajor = x;
si->si_uminor = y;
+ si->si_inode = 0;
LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash);
sysref_activate(&si->si_sysref);
{
if (dev == NULL)
return NOUDEV;
- if ((dev->si_umajor & 0xffffff00) ||
- (dev->si_uminor & 0x0000ff00)) {
- return NOUDEV;
- }
- return((dev->si_umajor << 8) | dev->si_uminor);
+
+ return (udev_t)dev->si_inode;
}
/*
cdev_t
udev2dev(udev_t x, int b)
{
- cdev_t dev;
- struct dev_ops *ops;
-
if (x == NOUDEV || b != 0)
return(NULL);
- ops = dev_ops_get(umajor(x), uminor(x));
- if (ops == NULL)
- return(NULL);
- dev = hashdev(ops, umajor(x), uminor(x), TRUE);
- return(dev);
+
+ return devfs_find_device_by_udev(x);
}
int
make_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
int perms, const char *fmt, ...)
{
- cdev_t dev;
+ cdev_t devfs_dev;
__va_list ap;
int i;
+ char dev_name[PATH_MAX+1];
/*
* compile the cdevsw and install the device
*/
compile_dev_ops(ops);
- dev = hashdev(ops, ops->head.maj, minor, FALSE);
/*
* Set additional fields (XXX DEVFS interface goes here)
*/
__va_start(ap, fmt);
- i = kvcprintf(fmt, NULL, dev->si_name, 32, ap);
- dev->si_name[i] = '\0';
- dev->si_uid = uid;
+ i = kvcprintf(fmt, NULL, dev_name, 32, ap);
+ dev_name[i] = '\0';
__va_end(ap);
- return (dev);
+/*
+ if ((devfs_dev = devfs_find_device_by_name(dev_name)) != NULL) {
+ kprintf("make_dev: Device %s already exists, returning old dev without creating new node\n", dev_name);
+ return devfs_dev;
+ }
+*/
+
+ devfs_dev = devfs_new_cdev(ops, minor);
+ memcpy(devfs_dev->si_name, dev_name, i+1);
+
+ devfs_debug(DEVFS_DEBUG_INFO, "make_dev called for %s\n", devfs_dev->si_name);
+ devfs_create_dev(devfs_dev, uid, gid, perms);
+
+ return (devfs_dev);
}
+
+cdev_t
+make_only_devfs_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
+ int perms, const char *fmt, ...)
+{
+ cdev_t devfs_dev;
+ __va_list ap;
+ int i;
+ //char *dev_name;
+
+ /*
+ * compile the cdevsw and install the device
+ */
+ compile_dev_ops(ops);
+ devfs_dev = devfs_new_cdev(ops, minor);
+
+ /*
+ * Set additional fields (XXX DEVFS interface goes here)
+ */
+ __va_start(ap, fmt);
+ i = kvcprintf(fmt, NULL, devfs_dev->si_name, 32, ap);
+ devfs_dev->si_name[i] = '\0';
+ __va_end(ap);
+
+
+ devfs_create_dev(devfs_dev, uid, gid, perms);
+
+ return (devfs_dev);
+}
+
+
+cdev_t
+make_only_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
+ int perms, const char *fmt, ...)
+{
+ cdev_t devfs_dev;
+ __va_list ap;
+ int i;
+ //char *dev_name;
+
+ /*
+ * compile the cdevsw and install the device
+ */
+ compile_dev_ops(ops);
+ devfs_dev = devfs_new_cdev(ops, minor);
+ devfs_dev->si_perms = perms;
+ devfs_dev->si_uid = uid;
+ devfs_dev->si_gid = gid;
+
+ /*
+ * Set additional fields (XXX DEVFS interface goes here)
+ */
+ __va_start(ap, fmt);
+ i = kvcprintf(fmt, NULL, devfs_dev->si_name, 32, ap);
+ devfs_dev->si_name[i] = '\0';
+ __va_end(ap);
+
+ reference_dev(devfs_dev);
+
+ return (devfs_dev);
+}
+
+void
+destroy_only_dev(cdev_t dev)
+{
+ devfs_destroy_cdev(dev);
+}
+
+
/*
* This function is similar to make_dev() but no cred information or name
* need be specified.
if (dev == NULL)
return;
+
+ devfs_debug(DEVFS_DEBUG_DEBUG, "destroy_dev called for %s\n", dev->si_name);
+ devfs_destroy_dev(dev);
+
+ return;
+
if ((dev->si_flags & SI_ADHOC) == 0) {
release_dev(dev);
return;
* We have to release the ops reference before we replace the
* device switch with dead_dev_ops.
*/
+
+
if (dead_dev_ops.d_strategy == NULL)
compile_dev_ops(&dead_dev_ops);
if (dev->si_ops && dev->si_ops != &dead_dev_ops)
dev->si_drv2 = NULL;
dev->si_ops = &dead_dev_ops;
sysref_put(&dev->si_sysref); /* release adhoc association */
+
release_dev(dev); /* release callers reference */
}
}
}
+
+int
+make_dev_alias(cdev_t target, const char *fmt, ...)
+{
+ char name[PATH_MAX + 1];
+ __va_list ap;
+ int i;
+
+ __va_start(ap, fmt);
+ i = kvcprintf(fmt, NULL, name, 32, ap);
+ name[i] = '\0';
+ __va_end(ap);
+
+ devfs_make_alias(name, target);
+
+ return 0;
+}
+
+
/*
* Add a reference to a device. Callers generally add their own references
* when they are going to store a device node in a variable for long periods
cdev_t
reference_dev(cdev_t dev)
{
+ //kprintf("reference_dev\n");
+
if (dev != NULL) {
sysref_get(&dev->si_sysref);
if (dev_ref_debug) {
void
release_dev(cdev_t dev)
{
+ //kprintf("release_dev\n");
+
if (dev == NULL)
return;
sysref_put(&dev->si_sysref);
make_dev(&fildesc_ops, fd,
UID_BIN, GID_BIN, 0666, "fd/%d", fd);
}
+
+ kprintf("fildesc_drvinit() building stdin, stdout, stderr: \n");
+
make_dev(&fildesc_ops, 0, UID_ROOT, GID_WHEEL, 0666, "stdin");
make_dev(&fildesc_ops, 1, UID_ROOT, GID_WHEEL, 0666, "stdout");
make_dev(&fildesc_ops, 2, UID_ROOT, GID_WHEEL, 0666, "stderr");
#include <sys/proc.h>
#include <machine/stdarg.h>
#include <sys/thread2.h>
+#include <vfs/devfs/devfs.h>
/*
* system link descriptors identify the command in the
int
dev_ops_add(struct dev_ops *ops, u_int mask, u_int match)
{
+ return 0;
+
static int next_maj = 256; /* first dynamic major number */
struct dev_ops_maj *rbmaj;
struct dev_ops_link *link;
struct dev_ops_maj *rbmaj;
struct dev_ops_link *link;
+ return NULL;
+
rbmaj = dev_ops_rb_tree_RB_LOOKUP(&dev_ops_rbhead, x);
if (rbmaj == NULL)
return(NULL);
}
/*
- * Take a cookie cutter to the major/minor device space for the passed
- * device and generate a new dev_ops visible to userland which the caller
- * can then modify. The original device is not modified but portions of
- * its major/minor space will no longer be visible to userland.
- */
-struct dev_ops *
-dev_ops_add_override(cdev_t backing_dev, struct dev_ops *template,
- u_int mask, u_int match)
-{
- struct dev_ops *ops;
- struct dev_ops *backing_ops = backing_dev->si_ops;
-
- ops = kmalloc(sizeof(struct dev_ops), M_DEVBUF, M_INTWAIT);
- *ops = *template;
- ops->head.name = backing_ops->head.name;
- ops->head.maj = backing_ops->head.maj;
- ops->head.flags |= backing_ops->head.flags & ~D_TRACKCLOSE;
- compile_dev_ops(ops);
- dev_ops_add(ops, mask, match);
-
- return(ops);
-}
-
-void
-dev_ops_remove_override(struct dev_ops *ops, u_int mask, u_int match)
-{
- dev_ops_remove(ops, mask, match);
- if (ops->head.refs) {
- kprintf("dev_ops_remove_override: %s still has %d refs!\n",
- ops->head.name, ops->head.refs);
- } else {
- bzero(ops, sizeof(*ops));
- kfree(ops, M_DEVBUF);
- }
-}
-
-/*
* Remove all matching dev_ops entries from the dev_ops_array[] major
* array so no new user opens can be performed, and destroy all devices
* installed in the hash table that are associated with this dev_ops. (see
return 0;
}
-/*
- * dev_ops_scan() - Issue a callback for all installed dev_ops structures.
- *
- * The scan will terminate if a callback returns a negative number.
- */
-struct dev_ops_scan_info {
- int (*callback)(struct dev_ops *, void *);
- void *arg;
-};
-
-static
-int
-dev_ops_scan_callback(struct dev_ops_maj *rbmaj, void *arg)
+int dev_ops_remove_all(struct dev_ops *ops)
{
- struct dev_ops_scan_info *info = arg;
- struct dev_ops_link *link;
- int count = 0;
- int r;
-
- for (link = rbmaj->link; link; link = link->next) {
- r = info->callback(link->ops, info->arg);
- if (r < 0)
- return(r);
- count += r;
- }
- return(count);
+ return devfs_destroy_dev_by_ops(ops, -1);
}
-int
-dev_ops_scan(int (*callback)(struct dev_ops *, void *), void *arg)
+int dev_ops_remove_minor(struct dev_ops *ops, int minor)
{
- struct dev_ops_scan_info info = { callback, arg };
-
- return (dev_ops_rb_tree_RB_SCAN(&dev_ops_rbhead, NULL,
- dev_ops_scan_callback, &info));
+ return devfs_destroy_dev_by_ops(ops, minor);
}
-
/*
* Release a ops entry. When the ref count reaches zero, recurse
* through the stack.
void
dev_ops_release(struct dev_ops *ops)
{
+ return;
--ops->head.refs;
if (ops->head.refs == 0) {
/* XXX */
#include <sys/sysctl.h>
#include <sys/buf.h>
#include <sys/conf.h>
+#include <sys/disklabel.h>
+#include <sys/disklabel32.h>
+#include <sys/disklabel64.h>
#include <sys/diskslice.h>
+#include <sys/diskmbr.h>
#include <sys/disk.h>
#include <sys/malloc.h>
#include <sys/sysctl.h>
#include <sys/msgport.h>
#include <sys/msgport2.h>
#include <sys/buf2.h>
+#include <vfs/devfs/devfs.h>
+
+#include <sys/thread2.h>
+
+#include <sys/queue.h>
+#include <sys/lock.h>
static MALLOC_DEFINE(M_DISK, "disk", "disk data");
+static void disk_msg_autofree_reply(lwkt_port_t, lwkt_msg_t);
+static void disk_msg_core(void *);
+static int disk_probe_slice(struct disk *dp, cdev_t dev, int slice);
+static void disk_probe(struct disk *dp);
+
static d_open_t diskopen;
static d_close_t diskclose;
static d_ioctl_t diskioctl;
.d_clone = diskclone
};
+static struct objcache *disk_msg_cache;
+
+struct objcache_malloc_args disk_msg_malloc_args = {
+ sizeof(struct disk_msg), M_DISK };
+
+static struct lwkt_port disk_dispose_port;
+static struct lwkt_port disk_msg_port;
+
+
+static int
+disk_probe_slice(struct disk *dp, cdev_t dev, int slice)
+{
+ struct disk_info *info = &dp->d_info;
+ struct diskslice *sp = &dp->d_slice->dss_slices[slice];
+ disklabel_ops_t ops;
+ struct partinfo part;
+ const char *msg;
+ cdev_t ndev;
+ unsigned long i;
+
+ //lp.opaque = NULL;
+
+ ops = &disklabel32_ops;
+ msg = ops->op_readdisklabel(dev, sp, &sp->ds_label, info);
+ if (msg && !strcmp(msg, "no disk label")) {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe_slice: trying with disklabel64\n");
+ ops = &disklabel64_ops;
+ msg = ops->op_readdisklabel(dev, sp, &sp->ds_label, info);
+ }
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe_slice: label: %s\n", (msg)?msg:"is NULL");
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe_slice: found %d partitions in the label\n", ops->op_getnumparts(sp->ds_label));
+ if (msg == NULL) {
+ if (slice != WHOLE_DISK_SLICE)
+ ops->op_adjust_label_reserved(dp->d_slice, slice, sp);
+ else
+ sp->ds_reserved = 0;
+
+ sp->ds_ops = ops;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe_slice: lp.opaque: %x\n", sp->ds_label.opaque);
+ for (i = 0; i < ops->op_getnumparts(sp->ds_label); i++) {
+ ops->op_loadpartinfo(sp->ds_label, i, &part);
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe_slice: partinfo says fstype=%d for part %d\n", part.fstype, i);
+ if (part.fstype) {
+ ndev = make_only_devfs_dev(&disk_ops,
+ dkmakeminor(dkunit(dp->d_cdev), slice, i),
+ UID_ROOT, GID_OPERATOR, 0640,
+ "%s%c", dev->si_name, 'a'+ (char)i);
+#if 0
+ make_dev_alias(ndev, "disk-by-id/diskTEST-sliceTEST-part%d", i);
+#endif
+ ndev->si_disk = dp;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe_slice:end: lp.opaque: %x\n", ndev->si_disk->d_slice->dss_slices[slice].ds_label.opaque);
+ }
+ }
+ } else if (info->d_dsflags & DSO_COMPATLABEL) {
+ msg = NULL;
+ if (sp->ds_size >= 0x100000000ULL)
+ ops = &disklabel64_ops;
+ else
+ ops = &disklabel32_ops;
+ sp->ds_label = ops->op_clone_label(info, sp);
+ } else {
+ if (sp->ds_type == DOSPTYP_386BSD /* XXX */)
+ log(LOG_WARNING, "%s: cannot find label (%s)\n",
+ dev->si_name, msg);
+ }
+
+ if (msg == NULL) {
+ sp->ds_wlabel = FALSE;
+ }
+
+ return (msg ? EINVAL : 0);
+}
+
+
+static void
+disk_probe(struct disk *dp)
+{
+ struct disk_info *info = &dp->d_info;
+ cdev_t dev = dp->d_cdev;
+ cdev_t ndev;
+ int error, i;
+
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe called for %s\n", dp->d_cdev->si_name);
+ KKASSERT (info->d_media_blksize != 0);
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe: info set!\n");
+
+ dp->d_slice = dsmakeslicestruct(BASE_SLICE, info);
+
+ error = mbrinit(dev, info, &(dp->d_slice));
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe: &dp->d_slice is: %x, %x\n", &dp->d_slice, dp->d_slice);
+ if (error != 0) {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe: mbrinit() failed with error: %d\n", error);
+ return;
+ } else {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "mbrinit succeeded, found %d slices\n", dp->d_slice->dss_nslices);
+ if (dp->d_slice->dss_nslices == BASE_SLICE) {
+ dp->d_slice->dss_slices[COMPATIBILITY_SLICE].ds_size = info->d_media_blocks;
+ dp->d_slice->dss_slices[COMPATIBILITY_SLICE].ds_reserved = 0;
+ ndev = make_only_devfs_dev(&disk_ops,
+ dkmakewholeslice(dkunit(dev), COMPATIBILITY_SLICE),
+ UID_ROOT, GID_OPERATOR, 0640,
+ "%ss%d", dev->si_name, COMPATIBILITY_SLICE);
+
+ ndev->si_disk = dp;
+ dp->d_slice->dss_slices[COMPATIBILITY_SLICE].ds_dev = ndev;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe: type of slice is :%x\n", dp->d_slice->dss_slices[COMPATIBILITY_SLICE].ds_type );
+ //if (dp->d_slice->dss_slices[COMPATIBILITY_SLICE].ds_type == DOSPTYP_386BSD) {
+ dp->d_slice->dss_first_bsd_slice = COMPATIBILITY_SLICE;
+ disk_probe_slice(dp, ndev, COMPATIBILITY_SLICE);
+ //}
+ }
+ for (i = BASE_SLICE; i < dp->d_slice->dss_nslices; i++) {
+ ndev = make_only_devfs_dev(&disk_ops,
+ dkmakewholeslice(dkunit(dev), i),
+ UID_ROOT, GID_OPERATOR, 0640,
+ "%ss%d", dev->si_name, i-1);
+ make_dev_alias(ndev, "disk-by-id/diskTEST-slice%d", i-1);
+
+ ndev->si_disk = dp;
+ dp->d_slice->dss_slices[i].ds_dev = ndev;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_probe-> type of slice is :%x\n", dp->d_slice->dss_slices[i].ds_type );
+ if (dp->d_slice->dss_slices[i].ds_type == DOSPTYP_386BSD) {
+ if (!dp->d_slice->dss_first_bsd_slice)
+ dp->d_slice->dss_first_bsd_slice = i;
+ disk_probe_slice(dp, ndev, i);
+ }
+ }
+ }
+}
+
+
+static void
+disk_msg_core(void *arg)
+{
+ uint8_t run = 1;
+ struct disk *dp;
+ struct diskslice *sp;
+ disk_msg_t msg;
+
+
+ lwkt_initport_thread(&disk_msg_port, curthread);
+ wakeup(curthread);
+
+ while (run) {
+ msg = (disk_msg_t)lwkt_waitport(&disk_msg_port, 0);
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_msg_core, new msg: %x\n", (unsigned int)msg->hdr.u.ms_result);
+
+ switch (msg->hdr.u.ms_result) {
+
+ case DISK_DISK_PROBE:
+ dp = (struct disk *)msg->load;
+ disk_probe(dp);
+ break;
+
+ case DISK_DISK_DESTROY:
+ dp = (struct disk *)msg->load;
+ devfs_destroy_subnames(dp->d_cdev->si_name);
+ devfs_destroy_dev(dp->d_cdev);
+ //devfs_destroy_dev(dp->d_rawdev); //XXX: needed? when?
+ break;
+
+ case DISK_SLICE_REPROBE:
+ dp = (struct disk *)msg->load;
+ sp = (struct diskslice *)msg->load2;
+ devfs_destroy_subnames(sp->ds_dev->si_name);
+ disk_probe_slice(dp, sp->ds_dev, dkslice(sp->ds_dev));
+ break;
+
+ case DISK_DISK_REPROBE:
+ dp = (struct disk *)msg->load;
+ devfs_destroy_subnames(dp->d_cdev->si_name);
+ disk_probe(dp);
+ break;
+
+ case DISK_SYNC:
+ break;
+
+ default:
+ devfs_debug(DEVFS_DEBUG_WARNING, "disk_msg_core: unknown message received at core\n");
+ }
+
+ lwkt_replymsg((lwkt_msg_t)msg, 0);
+ }
+ lwkt_exit();
+}
+
+
+/**
+ * Acts as a message drain. Any message that is replied to here gets destroyed and
+ * the memory freed.
+ **/
+static void
+disk_msg_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
+{
+ objcache_put(disk_msg_cache, msg);
+}
+
+
+void
+disk_msg_send(uint32_t cmd, void *load, void *load2)
+{
+ disk_msg_t disk_msg;
+ lwkt_port_t port = &disk_msg_port;
+
+ disk_msg = objcache_get(disk_msg_cache, M_WAITOK);
+
+ lwkt_initmsg(&disk_msg->hdr, &disk_dispose_port, 0);
+
+ disk_msg->hdr.u.ms_result = cmd;
+ disk_msg->load = load;
+ disk_msg->load2 = load2;
+ KKASSERT(port);
+ lwkt_sendmsg(port, (lwkt_msg_t)disk_msg);
+}
+
/*
* Create a raw device for the dev_ops template (which is returned). Also
* create a slice and unit managed disk and overload the user visible
disk_create(int unit, struct disk *dp, struct dev_ops *raw_ops)
{
cdev_t rawdev;
- struct dev_ops *dev_ops;
- /*
- * Create the raw backing device
- */
- compile_dev_ops(raw_ops);
- rawdev = make_dev(raw_ops, dkmakewholedisk(unit),
+ rawdev = make_only_dev(raw_ops, dkmakewholedisk(unit),
UID_ROOT, GID_OPERATOR, 0640,
"%s%d", raw_ops->head.name, unit);
- bzero(dp, sizeof(*dp));
- /*
- * We install a custom cdevsw rather then the passed cdevsw,
- * and save our disk structure in d_data so we can get at it easily
- * without any complex cloning code.
- */
- dev_ops = dev_ops_add_override(rawdev, &disk_ops,
- dkunitmask(), dkmakeunit(unit));
- dev_ops->head.data = dp;
+ bzero(dp, sizeof(*dp));
dp->d_rawdev = rawdev;
dp->d_raw_ops = raw_ops;
- dp->d_dev_ops = dev_ops;
- dp->d_cdev = make_dev(dev_ops,
+ dp->d_dev_ops = &disk_ops;
+ dp->d_cdev = make_only_devfs_dev(&disk_ops,
dkmakewholedisk(unit),
UID_ROOT, GID_OPERATOR, 0640,
- "%s%d", dev_ops->head.name, unit);
+ "%s%d", raw_ops->head.name, unit);
+
+ dp->d_cdev->si_disk = dp;
+
+ disk_ops.head.data = dp;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_create called for %s\n", dp->d_cdev->si_name);
LIST_INSERT_HEAD(&disklist, dp, d_list);
return (dp->d_rawdev);
}
void
disk_setdiskinfo(struct disk *disk, struct disk_info *info)
{
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_setdiskinfo called for disk -1-: %x\n", disk);
bcopy(info, &disk->d_info, sizeof(disk->d_info));
info = &disk->d_info;
disk->d_cdev->si_bsize_phys = disk->d_rawdev->si_bsize_phys;
disk->d_cdev->si_bsize_best = disk->d_rawdev->si_bsize_best;
}
+
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_setdiskinfo called for disk -2-: %x\n", disk);
+ disk_msg_send(DISK_DISK_PROBE, disk, NULL);
}
/*
void
disk_destroy(struct disk *disk)
{
- u_int match;
-
- if (disk->d_dev_ops) {
- match = dkmakeunit(dkunit(disk->d_cdev));
- dev_ops_remove_override(disk->d_dev_ops, dkunitmask(), match);
- LIST_REMOVE(disk, d_list);
- }
- if (disk->d_raw_ops) {
- match = dkmakeunit(dkunit(disk->d_rawdev));
- destroy_all_devs(disk->d_raw_ops, dkunitmask(), match);
- }
- bzero(disk, sizeof(*disk));
+ disk_msg_send(DISK_DISK_DESTROY, disk, NULL);
+ return;
}
int
void
disk_invalidate (struct disk *disk)
{
+ devfs_debug(DEVFS_DEBUG_INFO, "disk_invalidate for %s\n", disk->d_cdev->si_name);
if (disk->d_slice)
dsgone(&disk->d_slice);
}
struct disk *dp;
int error;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskopen: name is %s\n", dev->si_name);
+
/*
* dp can't be NULL here XXX.
*/
}
dp->d_flags |= DISKFLAG_LOCK;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskopen: -2- name is %s\n", dev->si_name);
+
/*
* Open the underlying raw device.
*/
error = dev_dopen(dp->d_rawdev, ap->a_oflags,
ap->a_devtype, ap->a_cred);
}
-
+#if 0
/*
* Inherit properties from the underlying device now that it is
* open.
*/
dev_dclone(dev);
+#endif
if (error)
goto out;
-
error = dsopen(dev, ap->a_devtype, dp->d_info.d_dsflags,
&dp->d_slice, &dp->d_info);
-
- if (!dsisopen(dp->d_slice))
+ if (!dsisopen(dp->d_slice)) {
dev_dclose(dp->d_rawdev, ap->a_oflags, ap->a_devtype);
+ }
out:
dp->d_flags &= ~DISKFLAG_LOCK;
if (dp->d_flags & DISKFLAG_WANTED) {
error = 0;
dp = dev->si_disk;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskclose: name %s\n", dev->si_name);
+
dsclose(dev, ap->a_devtype, dp->d_slice);
- if (!dsisopen(dp->d_slice))
+ if (!dsisopen(dp->d_slice)) {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskclose is closing underlying device\n");
error = dev_dclose(dp->d_rawdev, ap->a_fflag, ap->a_devtype);
+ }
return (error);
}
dp = dev->si_disk;
if (dp == NULL)
return (ENXIO);
+
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskioctl: cmd is: %x (name: %s)\n", ap->a_cmd, dev->si_name);
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskioctl: &dp->d_slice is: %x, %x\n", &dp->d_slice, dp->d_slice);
+
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskioctl:1: says lp.opaque is: %x\n", dp->d_slice->dss_slices[0].ds_label.opaque);
+
error = dsioctl(dev, ap->a_cmd, ap->a_data, ap->a_fflag,
&dp->d_slice, &dp->d_info);
+
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskioctl:2: says lp.opaque is: %x\n", dp->d_slice->dss_slices[0].ds_label.opaque);
+
if (error == ENOIOCTL) {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskioctl: going for dev_dioctl instead!\n");
error = dev_dioctl(dp->d_rawdev, ap->a_cmd, ap->a_data,
ap->a_fflag, ap->a_cred);
}
* returns NULL it will have handled the bio for us (e.g. EOF
* or error due to being beyond the device size).
*/
- if ((nbio = dscheck(dev, bio, dp->d_slice)) != NULL)
+ if ((nbio = dscheck(dev, bio, dp->d_slice)) != NULL) {
dev_dstrategy(dp->d_rawdev, nbio);
- else
+ } else {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "diskstrategy: dscheck NULL!!! biodone time!\n");
biodone(bio);
+ }
return(0);
}
{
cdev_t dev = ap->a_head.a_dev;
struct disk *dp;
-
+//XXX: need changes for devfs
dp = dev->si_ops->head.data;
KKASSERT(dp != NULL);
dev->si_disk = dp;
diskerr(struct bio *bio, cdev_t dev, const char *what, int pri, int donecnt)
{
struct buf *bp = bio->bio_buf;
- int unit = dkunit(dev);
- int slice = dkslice(dev);
- int part = dkpart(dev);
- char partname[2];
- char *sname;
const char *term;
switch(bp->b_cmd) {
term = "access";
break;
}
- sname = dsname(dev, unit, slice, part, partname);
- kprintf("%s%s: %s %sing ", sname, partname, what, term);
+ //sname = dsname(dev, unit, slice, part, partname);
+ kprintf("%s: %s %sing ", dev->si_name, what, term);
kprintf("offset %012llx for %d",
(long long)bio->bio_offset,
bp->b_bcount);
+
if (donecnt)
kprintf(" (%d bytes completed)", donecnt);
}
cdev_t
disk_locate(const char *devname)
{
- struct disk *dp;
- cdev_t dev;
- char *ptr;
- int i;
- int prefix;
- int slice;
- int part;
+ return devfs_find_device_by_name(devname);
+}
- /*
- * Device and unit
- */
- for (i = 0; devname[i]; ++i) {
- if (devname[i] >= '0' && devname[i] <= '9')
- break;
- }
- while (devname[i] >= '0' && devname[i] <= '9')
- ++i;
- prefix = i;
- /*
- * Slice and partition. s1 starts at slice #2. s0 is slice #0.
- * slice #1 is the WHOLE_DISK_SLICE.
- */
- if (devname[i] == 's') {
- slice = strtol(devname + i + 1, &ptr, 10);
- i = (const char *)ptr - devname;
- if (slice > 0)
- ++slice;
- } else {
- slice = WHOLE_DISK_SLICE;
- }
- if (devname[i] >= 'a' && devname[i] <= 'z') {
- part = devname[i] - 'a';
- } else {
- part = WHOLE_SLICE_PART;
- }
+void
+disk_config(void *arg)
+{
+ struct lwkt_port rep_port;
+ disk_msg_t disk_msg = objcache_get(disk_msg_cache, M_WAITOK);
+ disk_msg_t msg_incoming;
+ lwkt_port_t port = &disk_msg_port;
+
+ lwkt_initport_thread(&rep_port, curthread);
+ lwkt_initmsg(&disk_msg->hdr, &rep_port, 0);
+ kprintf("disk_config: sync'ing up\n");
+ disk_msg->hdr.u.ms_result = DISK_SYNC;
+
+ lwkt_sendmsg(port, (lwkt_msg_t)disk_msg);
+ msg_incoming = lwkt_waitport(&rep_port, 0);
+}
+
+
+static void
+disk_init(void)
+{
+ struct thread* td_core;
+ devfs_debug(DEVFS_DEBUG_DEBUG, "disk_init() called\n");
+
+ disk_msg_cache = objcache_create("disk-msg-cache", 0, 0,
+ NULL, NULL, NULL,
+ objcache_malloc_alloc,
+ objcache_malloc_free,
+ &disk_msg_malloc_args );
+
+ /* Initialize the reply-only port which acts as a message drain */
+ lwkt_initport_replyonly(&disk_dispose_port, disk_msg_autofree_reply);
+
+ lwkt_create(disk_msg_core, /*args*/NULL, &td_core, NULL,
+ 0, 0, "disk_msg_core");
+
+ tsleep(td_core, 0, "diskcore", 0);
+}
+
+
+static void
+disk_uninit(void)
+{
+ devfs_debug(DEVFS_DEBUG_DEBUG, "devfs_uninit() called\n");
+
+ objcache_destroy(disk_msg_cache);
- /*
- * Find the device
- */
- LIST_FOREACH(dp, &disklist, d_list) {
- dev = dp->d_cdev;
- if (strlen(dev->si_name) == prefix &&
- strncmp(devname, dev->si_name, prefix) == 0
- ) {
- return(dkmodpart(dkmodslice(dev, slice), part));
- }
- }
- return(NULL);
}
+
+SYSINIT(disk_register, SI_SUB_PRE_DRIVERS, SI_ORDER_FIRST, disk_init, NULL);
+SYSUNINIT(disk_register, SI_SUB_PRE_DRIVERS, SI_ORDER_ANY, disk_uninit, NULL);
/*
* The GPT starts in sector 1.
*/
- wdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), WHOLE_SLICE_PART);
+ wdev = dev;
dname = dev_dname(wdev);
bp1 = geteblk((int)info->d_media_blksize);
bp1->b_bio1.bio_offset = info->d_media_blksize;
if (lp->d_partitions[RAW_PART].p_offset != 0)
return (EXDEV); /* not quite right */
+
+ kprintf("this is l32_writedisklabel: part: %d, slice: %d\n", dkpart(dev), dkslice(dev));
+ kprintf("Avoiding disaster and returning now\n");
+ return 0;
+
bp = geteblk((int)lp->d_secsize);
bp->b_bio1.bio_offset = (off_t)LABELSECTOR32 * lp->d_secsize;
bp->b_bio1.bio_done = biodone_sync;
bp->b_bio1.bio_flags |= BIO_SYNC;
bp->b_bcount = lp->d_secsize;
+
#if 1
/*
* We read the label first to see if it's there,
lp = lpx.lab64;
+ kprintf("this is l64_writedisklabel: part: %d, slice: %d\n", dkpart(dev), dkslice(dev));
+ kprintf("Avoiding disaster and returning now\n");
+ return 0;
+
/*
* XXX I/O size is subject to device DMA limitations
*/
u_int64_t mbr_offset;
char partname[2];
u_long secpercyl;
- char *sname;
+ char *sname = "tempname";
struct diskslice *sp;
struct diskslices *ssp;
cdev_t wdev;
if (info->d_media_blksize & DEV_BMASK)
return (EIO);
/* Read master boot record. */
- wdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), WHOLE_SLICE_PART);
+ wdev = dev;
bp = geteblk((int)info->d_media_blksize);
bp->b_bio1.bio_offset = (off_t)mbr_offset * info->d_media_blksize;
bp->b_bio1.bio_done = biodone_sync;
/* Weakly verify it. */
cp = bp->b_data;
- sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, WHOLE_SLICE_PART, partname);
+ //sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, WHOLE_SLICE_PART, partname);
if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
if (bootverbose)
kprintf("%s: invalid primary partition table: no magic\n",
if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
&& dp->dp_start == 0 && dp->dp_size == 0)
continue;
- sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
- WHOLE_SLICE_PART, partname);
+ //sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
+ // WHOLE_SLICE_PART, partname);
/*
* Temporarily ignore errors from this check. We could
goto bad;
}
sp = &ssp->dss_slices[slice];
-
/*
* Calculate secno and nsec
*/
struct diskslice *sp;
struct diskslices *ssp;
+ kprintf("dsgone is called... fear!\n");
+
for (slice = 0, ssp = *sspp; slice < ssp->dss_nslices; slice++) {
sp = &ssp->dss_slices[slice];
free_ds_label(ssp, slice);
if (sp->ds_label.opaque == NULL &&
part == WHOLE_SLICE_PART &&
slice != WHOLE_DISK_SLICE) {
+ kprintf("dsioctl: I shouldn't be here...\n");
dsreadandsetlabel(dev, info->d_dsflags,
ssp, sp, info);
ops = sp->ds_ops; /* may be NULL */
}
lptmp.opaque = data;
error = ops->op_setdisklabel(lp, lptmp, ssp, sp, openmask);
+ //XXX: send reprobe message here.
+ disk_msg_send(DISK_SLICE_REPROBE, dev->si_disk, sp);
if (error != 0) {
kfree(lp.opaque, M_DEVBUF);
return (error);
}
}
+ disk_msg_send(DISK_DISK_REPROBE, dev->si_disk, NULL);
+ return 0;
+
/*
* Temporarily forget the current slices struct and read
* the current one.
* XXX should wait for current accesses on this disk to
* complete, then lock out future accesses and opens.
*/
+ kprintf("dsioctl messed with our stuff!\n");
*sspp = NULL;
error = dsopen(dev, S_IFCHR, ssp->dss_oflags, sspp, info);
if (error != 0) {
}
}
+ //XXX: recheck this...
dsgone(&ssp);
return (0);
old_wlabel = sp->ds_wlabel;
set_ds_wlabel(ssp, slice, TRUE);
error = ops->op_writedisklabel(dev, ssp, sp, sp->ds_label);
+ disk_msg_send(DISK_SLICE_REPROBE, dev->si_disk, sp);
set_ds_wlabel(ssp, slice, old_wlabel);
/* XXX should invalidate in-core label if write failed. */
return (error);
char *
dsname(cdev_t dev, int unit, int slice, int part, char *partname)
{
- static char name[32];
- const char *dname;
- int used;
-
- dname = dev_dname(dev);
- if (strlen(dname) > 16)
- dname = "nametoolong";
- ksnprintf(name, sizeof(name), "%s%d", dname, unit);
- partname[0] = '\0';
- used = strlen(name);
-
- if (slice != WHOLE_DISK_SLICE) {
- /*
- * slice or slice + partition. BASE_SLICE is s1, but
- * the compatibility slice (0) needs to be s0.
- */
- used += ksnprintf(name + used, sizeof(name) - used,
- "s%d", (slice ? slice - BASE_SLICE + 1 : 0));
- if (part != WHOLE_SLICE_PART) {
- used += ksnprintf(name + used, sizeof(name) - used,
- "%c", 'a' + part);
- partname[0] = 'a' + part;
- partname[1] = 0;
- }
- } else if (part == WHOLE_SLICE_PART) {
- /*
- * whole-disk-device, raw access to disk
- */
- /* no string extension */
- } else if (part > 128) {
- /*
- * whole-disk-device, extended raw access partitions.
- * (typically used to access CD audio tracks)
- */
- used += ksnprintf(name + used, sizeof(name) - used,
- "t%d", part - 128);
- } else {
- /*
- * whole-disk-device, illegal partition number
- */
- used += ksnprintf(name + used, sizeof(name) - used,
- "?%d", part);
- }
- return (name);
+ return dev->si_name;
}
/*
int slice;
int part;
+ ssp = *sspp;
dev->si_bsize_phys = info->d_media_blksize;
+ slice = dkslice(dev);
+ part = dkpart(dev);
+ sp = &ssp->dss_slices[slice];
+ dssetmask(sp, part);
+
+ return 0;
/*
* Do not attempt to read the slice table or disk label when
tp->t_dev = device;
if (!ISSET(tp->t_state, TS_ISOPEN)) {
SET(tp->t_state, TS_ISOPEN);
- if (ISSET(tp->t_cflag, CLOCAL))
+ if (ISSET(tp->t_cflag, CLOCAL)) {
SET(tp->t_state, TS_CONNECTED);
+ }
bzero(&tp->t_winsize, sizeof(tp->t_winsize));
}
ttsetwater(tp);
ttymalloc(struct tty *tp)
{
- if (tp)
+ if (tp) {
return(tp);
- tp = kmalloc(sizeof *tp, M_TTYS, M_WAITOK|M_ZERO);
+ }
+ tp = kmalloc(sizeof *tp, M_TTYS, M_WAITOK|M_ZERO);
ttyregister(tp);
return (tp);
}
static struct dev_ops cn_iops = {
{ "intercept", CDEV_MAJOR, D_TTY | D_KQFILTER },
- .d_default = cnintercept
+ .d_default = cnintercept
};
static struct dev_ops *cn_fwd_ops;
static cdev_t cn_dev;
-static udev_t cn_udev;
+
+//XXX: get this shit out! (alexh)
+#if 0
SYSCTL_OPAQUE(_machdep, CPU_CONSDEV, consdev, CTLFLAG_RD,
&cn_udev, sizeof cn_udev, "T,udev_t", "");
+#endif
static int cn_mute;
struct consdev *best_cp, *cp, **list;
/*
+ * Check if we should mute the console (for security reasons perhaps)
+ * It can be changes dynamically using sysctl kern.consmute
+ * once we are up and going.
+ *
+ */
+ cn_mute = ((boothowto & (RB_MUTE
+ |RB_SINGLE
+ |RB_VERBOSE
+ |RB_ASKNAME
+ |RB_CONFIG)) == RB_MUTE);
+
+ /*
* Find the first console with the highest priority.
*/
best_cp = NULL;
best_cp = cp;
}
- /*
- * Check if we should mute the console (for security reasons perhaps)
- * It can be changes dynamically using sysctl kern.consmute
- * once we are up and going.
- *
- */
- cn_mute = ((boothowto & (RB_MUTE
- |RB_SINGLE
- |RB_VERBOSE
- |RB_ASKNAME
- |RB_CONFIG)) == RB_MUTE);
/*
* If no console, give up.
cn_tab = best_cp;
}
+
/*
* Hook the open and close functions on the selected device.
*/
{
if ((cn_tab == NULL) || cn_mute)
return;
-
if (cn_tab->cn_dev == NULL) {
cn_tab->cn_init_fini(cn_tab);
- }
- if (cn_tab->cn_dev == NULL) {
- kprintf("Unable to hook console open and close! cn_tab %p\n",
- cn_tab);
- return;
+ if (cn_tab->cn_dev == NULL) {
+ kprintf("Unable to hook console! cn_tab %p\n", cn_tab);
+ return;
+ }
}
- /*
- * Hook the open and close functions. XXX bad hack.
- */
- if (dev_is_good(cn_tab->cn_dev)) {
- cn_fwd_ops = dev_ops_intercept(cn_tab->cn_dev, &cn_iops);
- }
+ cn_fwd_ops = dev_ops_intercept(cn_tab->cn_dev, &cn_iops);
cn_dev = cn_tab->cn_dev;
- cn_udev = dev2udev(cn_dev);
console_pausing = 0;
}
{
if (cn_tab == NULL)
return;
-
- /*
- * Unhook the open and close functions. XXX bad hack
- */
if (cn_fwd_ops)
dev_ops_restore(cn_tab->cn_dev, cn_fwd_ops);
cn_fwd_ops = NULL;
cn_dev = NULL;
- cn_udev = NOUDEV;
}
+
/*
* User has changed the state of the console muting.
* This may require us to open or close the device in question.
*/
if (cn_is_open) {
error = dev_dclose(cn_dev, openflag,
- openmode);
+ openmode);
}
if (error == 0)
cnuninit();
SYSCTL_PROC(_kern, OID_AUTO, consmute, CTLTYPE_INT|CTLFLAG_RW,
0, sizeof cn_mute, sysctl_kern_consmute, "I", "");
+
/*
* We intercept the OPEN and CLOSE calls on the original device, and
* forward the rest through.
cdev_t dev = ap->a_head.a_dev;
int flag = ap->a_oflags;
int mode = ap->a_devtype;
- cdev_t cndev, physdev;
+ cdev_t cndev;
+ cdev_t physdev;
int retval = 0;
if (cn_tab == NULL || cn_fwd_ops == NULL)
return (0);
- cndev = cn_tab->cn_dev;
- physdev = (major(dev) == major(cndev) ? dev : cndev);
+
+ cndev = cn_tab->cn_dev; /* actual physical device */
+ physdev = (dev == cn_devfsdev) ? cndev : dev;
/*
* If mute is active, then non console opens don't get here
retval = dev_doperate_ops(cn_fwd_ops, &ap->a_head);
}
if (retval == 0) {
- /*
- * check if we openned it via /dev/console or
+ /*
+ * check if we openned it via /dev/console or
* via the physical entry (e.g. /dev/sio0).
*/
- if (dev == cndev)
+ if (dev == cndev) {
cn_phys_is_open = 1;
- else if (physdev == cndev) {
+ } else if (physdev == cndev) {
openmode = mode;
openflag = flag;
cn_is_open = 1;
}
- dev->si_tty = physdev->si_tty;
+ dev->si_tty = cndev->si_tty;
}
return (retval);
}
static int
cnclose(struct dev_close_args *ap)
{
- cdev_t dev = ap->a_head.a_dev;
- cdev_t cndev;
struct tty *cn_tp;
+ cdev_t cndev;
+ cdev_t physdev;
+ cdev_t dev = ap->a_head.a_dev;
if (cn_tab == NULL || cn_fwd_ops == NULL)
- return (0);
+ return(0);
cndev = cn_tab->cn_dev;
cn_tp = cndev->si_tty;
+ physdev = (dev == cn_devfsdev) ? cndev : dev;
+
/*
* act appropriatly depending on whether it's /dev/console
* or the pysical device (e.g. /dev/sio) that's being closed.
/* reset session and proc group */
ttyclearsession(cn_tp);
}
- return (0);
+ return(0);
}
- } else if (major(dev) != major(cndev)) {
+ } else if (physdev == cndev) {
/* the logical console is about to be closed */
cn_is_open = 0;
if (cn_phys_is_open)
- return (0);
+ return(0);
dev = cndev;
}
if (cn_fwd_ops) {
cn_drvinit(void *unused)
{
dev_ops_add(&cn_ops, 0, 0);
- cn_devfsdev = make_dev(&cn_ops, 0, UID_ROOT, GID_WHEEL,
+ cn_devfsdev = make_only_devfs_dev(&cn_ops, 0, UID_ROOT, GID_WHEEL,
0600, "console");
}
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/thread2.h>
+#include <vfs/devfs/devfs.h>
+
+DEVFS_DECLARE_CLONE_BITMAP(pty);
+DEVFS_DECLARE_CLONE_BITMAP(pts);
MALLOC_DEFINE(M_PTY, "ptys", "pty data structures");
static d_read_t ptcread;
static d_write_t ptcwrite;
static d_poll_t ptcpoll;
+static d_clone_t ptyclone;
#define CDEV_MAJOR_S 5
static struct dev_ops pts_ops = {
struct tty pt_tty;
cdev_t devs, devc;
struct prison *pt_prison;
+ short ref_count;
};
#define PF_PKT 0x08 /* packet mode */
ttyregister(&pt->pt_tty);
}
+static int
+ptyclone(struct dev_clone_args *ap)
+{
+ int unit;
+ struct pt_ioctl *pt;
+
+ unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), 256);
+
+ if (unit < 0)
+ return 1;
+
+ pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
+ pt->ref_count++;
+ pt->devc = ap->a_dev = make_only_dev(&ptc_ops, unit, ap->a_cred->cr_ruid, 0, 0600, "ptm/%d", unit);
+ pt->devs = make_dev(&pts_ops, unit, ap->a_cred->cr_ruid, 0, 0600, "pts/%d", unit);
+
+ //reference_dev(pt->devc);
+ //reference_dev(pt->devs);
+
+ pt->devs->si_drv1 = pt->devc->si_drv1 = pt;
+ pt->devs->si_tty = pt->devc->si_tty = &pt->pt_tty;
+ pt->pt_tty.t_dev = pt->devs;
+ ttyregister(&pt->pt_tty);
+
+ return 0;
+}
+
/*ARGSUSED*/
static int
ptsopen(struct dev_open_args *ap)
if (!dev->si_drv1)
ptyinit(minor(dev));
if (!dev->si_drv1)
- return(ENXIO);
+ return(ENXIO);
pti = dev->si_drv1;
tp = dev->si_tty;
if ((tp->t_state & TS_ISOPEN) == 0) {
error = (*linesw[tp->t_line].l_open)(dev, tp);
if (error == 0)
ptcwakeup(tp, FREAD|FWRITE);
+
+#if 0
+ /* unix98 pty stuff */
+ if ((!error) && (!memcmp(dev->si_name, "pts/", 4))) {
+ ((struct pt_ioctl *)dev->si_drv1)->ref_count++;
+ //reference_dev(dev);
+ //reference_dev(((struct pt_ioctl *)dev->si_drv1)->devc);
+ //devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(pts), dev->si_uminor-300);
+ }
+#endif
+
return (error);
}
cdev_t dev = ap->a_head.a_dev;
struct tty *tp;
int err;
-
+#if 0
+ /* unix98 pty stuff */
+ if (!memcmp(dev->si_name, "pts/", 4)) {
+ if (--((struct pt_ioctl *)dev->si_drv1)->ref_count == 0) {
+ kfree(dev->si_drv1, M_PTY);
+ devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty), dev->si_uminor);
+ destroy_dev(dev);
+ }
+ }
+#endif
tp = dev->si_tty;
err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
ptsstop(tp, FREAD|FWRITE);
}
tp->t_oproc = 0; /* mark closed */
+#if 0
+ if (!memcmp(dev->si_name, "ptm/", 4)) {
+ ((struct pt_ioctl *)dev->si_drv1)->devc = NULL;
+ if (--((struct pt_ioctl *)dev->si_drv1)->ref_count == 0) {
+ kfree(dev->si_drv1, M_PTY);
+ devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty), dev->si_uminor);
+ }
+ //release_dev(dev);
+ //release_dev(((struct pt_ioctl *)dev->si_drv1)->devs);
+ }
+#endif
return (0);
}
static void
ptc_drvinit(void *unused)
{
+ int i;
dev_ops_add(&pts_ops, 0, 0);
dev_ops_add(&ptc_ops, 0, 0);
- /* XXX: Gross hack for DEVFS */
- /* XXX: DEVFS is no more, should this be removed? */
- ptyinit(0);
+
+ devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(pty));
+ devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(pts));
+
+#if 0
+ /* Unix98 pty stuff, leave out for now */
+ make_dev(&ptc_ops, 0, 0, 0, 0666, "ptmx");
+ devfs_clone_handler_add("ptmx", ptyclone);
+#endif
+ for (i = 0; i < 256; i++) {
+ ptyinit(i);
+ }
}
SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL)
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/device.h>
+#include <sys/disk.h>
#include <sys/namecache.h>
#include <sys/paths.h>
#include <sys/thread2.h>
+#include <sys/nlookup.h>
+#include <vfs/devfs/devfs.h>
#include "opt_ddb.h"
#ifdef DDB
NULL
};
+int vfs_mountroot_devfs(void);
static void vfs_mountroot(void *junk);
static int vfs_mountroot_try(const char *mountfrom);
static int vfs_mountroot_ask(void);
int i;
cdev_t save_rootdev = rootdev;
+ /*
+ * Make sure all disk devices created so far have also been probed,
+ * and also make sure that the newly created device nodes for
+ * probed disks are ready, too.
+ */
+ disk_config(NULL);
+ devfs_config(NULL);
+
/*
* The root filesystem information is compiled in, and we are
* booted with instructions to use it.
panic("Root mount failed, startup aborted.");
}
+
+int
+vfs_mountroot_devfs(void)
+{
+ struct vnode *vp;
+ struct nchandle nch;
+ struct nlookupdata nd;
+ struct mount *mp;
+ struct vfsconf *vfsp;
+ int error;
+ struct ucred *cred = proc0.p_ucred;
+
+ /*
+ * Lookup the requested path and extract the nch and vnode.
+ */
+ error = nlookup_init_raw(&nd,
+ "/dev", UIO_SYSSPACE, NLC_FOLLOW,
+ cred, &rootnch);
+
+ if (error == 0) {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "vfs_mountroot_devfs: nlookup_init is ok...\n");
+ if ((error = nlookup(&nd)) == 0) {
+ devfs_debug(DEVFS_DEBUG_DEBUG, "vfs_mountroot_devfs: nlookup is ok...\n");
+ if (nd.nl_nch.ncp->nc_vp == NULL) {
+ devfs_debug(DEVFS_DEBUG_SHOW, "vfs_mountroot_devfs: nlookup: simply not found\n");
+ error = ENOENT;
+ }
+ }
+ }
+ if (error) {
+ nlookup_done(&nd);
+ devfs_debug(DEVFS_DEBUG_SHOW, "vfs_mountroot_devfs: nlookup failed, error: %d\n", error);
+ return (error);
+ }
+
+ /*
+ * Extract the locked+refd ncp and cleanup the nd structure
+ */
+ nch = nd.nl_nch;
+ cache_zero(&nd.nl_nch);
+ nlookup_done(&nd);
+
+ /*
+ * now we have the locked ref'd nch and unreferenced vnode.
+ */
+ vp = nch.ncp->nc_vp;
+ if ((error = vget(vp, LK_EXCLUSIVE)) != 0) {
+ cache_put(&nch);
+ devfs_debug(DEVFS_DEBUG_SHOW, "vfs_mountroot_devfs: vget failed\n");
+ return (error);
+ }
+ cache_unlock(&nch);
+
+ if ((error = vinvalbuf(vp, V_SAVE, 0, 0)) != 0) {
+ cache_drop(&nch);
+ vput(vp);
+ devfs_debug(DEVFS_DEBUG_SHOW, "vfs_mountroot_devfs: vinvalbuf failed\n");
+ return (error);
+ }
+ if (vp->v_type != VDIR) {
+ cache_drop(&nch);
+ vput(vp);
+ devfs_debug(DEVFS_DEBUG_SHOW, "vfs_mountroot_devfs: vp is not VDIR\n");
+ return (ENOTDIR);
+ }
+
+ vfsp = vfsconf_find_by_name("devfs");
+ vp->v_flag |= VMOUNT;
+
+ /*
+ * Allocate and initialize the filesystem.
+ */
+ mp = kmalloc(sizeof(struct mount), M_MOUNT, M_ZERO|M_WAITOK);
+ TAILQ_INIT(&mp->mnt_nvnodelist);
+ TAILQ_INIT(&mp->mnt_reservedvnlist);
+ TAILQ_INIT(&mp->mnt_jlist);
+ mp->mnt_nvnodelistsize = 0;
+ lockinit(&mp->mnt_lock, "vfslock", 0, 0);
+ vfs_busy(mp, LK_NOWAIT);
+ mp->mnt_op = vfsp->vfc_vfsops;
+ mp->mnt_vfc = vfsp;
+ vfsp->vfc_refcount++;
+ mp->mnt_stat.f_type = vfsp->vfc_typenum;
+ mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
+ strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
+ mp->mnt_stat.f_owner = cred->cr_uid;
+ mp->mnt_iosize_max = DFLTPHYS;
+ vn_unlock(vp);
+
+ /*
+ * Mount the filesystem.
+ */
+ error = VFS_MOUNT(mp, "/dev", NULL, cred);
+
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+
+ /*
+ * Put the new filesystem on the mount list after root. The mount
+ * point gets its own mnt_ncmountpt (unless the VFS already set one
+ * up) which represents the root of the mount. The lookup code
+ * detects the mount point going forward and checks the root of
+ * the mount going backwards.
+ *
+ * It is not necessary to invalidate or purge the vnode underneath
+ * because elements under the mount will be given their own glue
+ * namecache record.
+ */
+ if (!error) {
+ if (mp->mnt_ncmountpt.ncp == NULL) {
+ /*
+ * allocate, then unlock, but leave the ref intact
+ */
+ cache_allocroot(&mp->mnt_ncmountpt, mp, NULL);
+ cache_unlock(&mp->mnt_ncmountpt);
+ }
+ mp->mnt_ncmounton = nch; /* inherits ref */
+ nch.ncp->nc_flag |= NCF_ISMOUNTPT;
+
+ /* XXX get the root of the fs and cache_setvp(mnt_ncmountpt...) */
+ vp->v_flag &= ~VMOUNT;
+ mountlist_insert(mp, MNTINS_LAST);
+ vn_unlock(vp);
+ //checkdirs(&mp->mnt_ncmounton, &mp->mnt_ncmountpt);
+ error = vfs_allocate_syncvnode(mp);
+ if (error) {
+ devfs_debug(DEVFS_DEBUG_SHOW, "vfs_mountroot_devfs: vfs_allocate_syncvnode failed\n");
+ }
+ vfs_unbusy(mp);
+ error = VFS_START(mp, 0);
+ vrele(vp);
+ } else {
+ vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_coherency_ops);
+ vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_journal_ops);
+ vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_norm_ops);
+ vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_spec_ops);
+ vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_fifo_ops);
+ vp->v_flag &= ~VMOUNT;
+ mp->mnt_vfc->vfc_refcount--;
+ vfs_unbusy(mp);
+ kfree(mp, M_MOUNT);
+ cache_drop(&nch);
+ vput(vp);
+ devfs_debug(DEVFS_DEBUG_SHOW, "vfs_mountroot_devfs: mount failed\n");
+ }
+
+ devfs_debug(DEVFS_DEBUG_DEBUG, "rootmount_devfs done with error: %d\n", error);
+ return (error);
+}
+
+
/*
* Mount (mountfrom) as the root filesystem.
*/
static int
vfs_mountroot_try(const char *mountfrom)
{
- struct mount *mp;
+ struct mount *mp, *mp2;
char *vfsname, *devname;
int error;
char patt[32];
vfsname = NULL;
devname = NULL;
mp = NULL;
+ mp2 = NULL;
error = EINVAL;
if (mountfrom == NULL)
error = VFS_MOUNT(mp, NULL, NULL, proc0.p_ucred);
+ if (!error) {
+ //kprintf("Trying vfs_mountroot_devfs!\n");
+ //vfs_mountroot_devfs();
+ }
+
done:
if (vfsname != NULL)
kfree(vfsname, M_MOUNT);
return(error);
}
+
+static void vfs_mountroot_ask_callback(cdev_t);
+
/*
* Spin prompting on the console for a suitable root filesystem
*/
-static int vfs_mountroot_ask_callback(struct dev_ops *ops, void *arg);
static int
vfs_mountroot_ask(void)
if (name[0] == 0) {
;
} else if (name[0] == '?') {
- kprintf("Possibly valid devices for 'ufs' root:\n");
- dev_ops_scan(vfs_mountroot_ask_callback, NULL);
+ kprintf("Possibly valid devices for root FS:\n");
+ //enumerate all disk devices
+ devfs_scan_callback(vfs_mountroot_ask_callback);
kprintf("\n");
continue;
} else if (strcmp(name, "panic") == 0) {
return(1);
}
-static int
-vfs_mountroot_ask_callback(struct dev_ops *ops, void *arg __unused)
-{
- cdev_t dev;
- dev = get_dev(ops->head.maj, 0);
+static void
+vfs_mountroot_ask_callback(cdev_t dev)
+{
if (dev_is_good(dev) && (dev_dflags(dev) & D_DISK))
- kprintf(" \"%s\"", dev_dname(dev));
- return(0);
+ kprintf(" \"%s\" ", dev->si_name);
}
+
static int
getline(char *cp, int limit)
{
cdev_t dev;
};
-static int kgetdiskbyname_callback(struct dev_ops *ops, void *arg);
cdev_t
kgetdiskbyname(const char *name)
int nlen;
int unit, slice, part;
cdev_t rdev;
- struct kdbn_info info;
/*
* Get the base name of the device
/*
* Locate the device
*/
- bzero(&info, sizeof(info));
- info.nlen = nlen;
- info.name = name;
- info.minor = dkmakeminor(unit, slice, part);
- dev_ops_scan(kgetdiskbyname_callback, &info);
- if (info.dev == NULL) {
+ rdev = devfs_find_device_by_name(name);
+ if (rdev == NULL) {
kprintf("no disk named '%s'\n", name);
- return (NULL);
}
-
/*
* FOUND DEVICE
*/
- rdev = make_sub_dev(info.dev, info.minor);
return(rdev);
}
-static int
-kgetdiskbyname_callback(struct dev_ops *ops, void *arg)
-{
- struct kdbn_info *info = arg;
- cdev_t dev;
- const char *dname;
-
- dev = get_dev(ops->head.maj, info->minor);
- if (dev_is_good(dev) && (dname = dev_dname(dev)) != NULL) {
- if (strlen(dname) == info->nlen &&
- strncmp(dname, info->name, info->nlen) == 0) {
- info->dev = dev;
- return(-1);
- }
- }
- return(0);
-}
-
/*
* Set rootdev to match (name), given that we expect it to
* refer to a disk-like device.
rootdev = diskdev;
return (0);
}
-
+ /* set to NULL if kgetdiskbyname() fails so that if the first rootdev is
+ * found by fails to mount and the second one isn't found, mountroot_try
+ * doesn't try again with the first one
+ */
+ rootdev = NULL;
return (1);
}
* Create a vnode for a block device.
* Used for mounting the root file system.
*/
+extern struct vop_ops *devfs_vnode_dev_vops_p;
int
bdevvp(cdev_t dev, struct vnode **vpp)
{
*vpp = NULLVP;
return (ENXIO);
}
- error = getspecialvnode(VT_NON, NULL, &spec_vnode_vops_p, &nvp, 0, 0);
+ error = getspecialvnode(VT_NON, NULL, &devfs_vnode_dev_vops_p/*&spec_vnode_vops_p*/, &nvp, 0, 0);
if (error) {
*vpp = NULLVP;
return (error);
}
vp = nvp;
vp->v_type = VCHR;
+ vp->v_rdev = dev;
vp->v_umajor = dev->si_umajor;
vp->v_uminor = dev->si_uminor;
vx_unlock(vp);
return (error);
}
if ((dev = vp->v_rdev) == NULL) {
- if ((dev = get_dev(vp->v_umajor, vp->v_uminor)) == NULL)
- return(0);
+ return(0);
}
reference_dev(dev);
lwkt_gettoken(&ilock, &spechash_token);
}
lwkt_reltoken(&ilock);
dev_drevoke(dev);
- release_dev(dev);
+ //release_dev(dev);
return (0);
}
cdev_t dev;
if ((dev = vp->v_rdev) == NULL) {
- if (vp->v_type != VBLK)
- dev = get_dev(vp->v_uminor, vp->v_umajor);
+/* if (vp->v_type != VBLK)
+ dev = get_dev(vp->v_uminor, vp->v_umajor); */
}
if (dev != NULL && dev->si_mountpoint)
return (EBUSY);
return (0);
}
- if ((dev = vp->v_rdev) == NULL) {
- get_mplock();
- dev = get_dev(vp->v_umajor, vp->v_uminor);
- rel_mplock();
- }
+ dev = vp->v_rdev;
if (dev == NULL) {
if (errp != NULL)
sb->st_nlink = vap->va_nlink;
sb->st_uid = vap->va_uid;
sb->st_gid = vap->va_gid;
- sb->st_rdev = makeudev(vap->va_rmajor, vap->va_rminor);
+ sb->st_rdev = dev2udev(vp->v_rdev);
sb->st_size = vap->va_size;
sb->st_atimespec = vap->va_atime;
sb->st_mtimespec = vap->va_mtime;
* to get a valid block size out of it?
*/
dev = vp->v_rdev;
- if (dev == NULL && vp->v_type == VCHR) {
- get_mplock();
- dev = get_dev(vp->v_umajor, vp->v_uminor);
- rel_mplock();
- }
+
sb->st_blksize = dev->si_bsize_best;
if (sb->st_blksize < dev->si_bsize_phys)
sb->st_blksize = dev->si_bsize_phys;
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <vfs/devfs/devfs.h>
+
struct netmsg_bpf_output {
struct netmsg nm_netmsg;
struct mbuf *nm_mbuf;
};
MALLOC_DEFINE(M_BPF, "BPF", "BPF data");
+DEVFS_DECLARE_CLONE_BITMAP(bpf);
#if NBPF > 0
static void bpf_drvinit(void *unused);
static d_open_t bpfopen;
+static d_clone_t bpfclone;
static d_close_t bpfclose;
static d_read_t bpfread;
static d_write_t bpfwrite;
*/
if (d != NULL)
return(EBUSY);
- make_dev(&bpf_ops, minor(dev), 0, 0, 0600, "bpf%d", lminor(dev));
+
MALLOC(d, struct bpf_d *, sizeof *d, M_BPF, M_WAITOK | M_ZERO);
dev->si_drv1 = d;
d->bd_bufsize = bpf_bufsize;
return(0);
}
+static int
+bpfclone(struct dev_clone_args *ap)
+{
+ int unit;
+
+ unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(bpf), 0);
+ ap->a_dev = make_only_dev(&bpf_ops, unit, 0, 0, 0600, "bpf%d", unit);
+
+ return 0;
+}
+
/*
* Close the descriptor by detaching it from its interface,
* deallocating its buffers, and marking it free.
crit_exit();
bpf_freed(d);
dev->si_drv1 = NULL;
+ devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(bpf), dev->si_uminor);
kfree(d, M_BPF);
-
return(0);
}
bpf_drvinit(void *unused)
{
dev_ops_add(&bpf_ops, 0, 0);
+ make_dev(&bpf_ops, 0, 0, 0, 0600, "bpf");
+ devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(bpf));
+ devfs_clone_handler_add("bpf", bpfclone);
+}
+
+static void
+bpf_drvuninit(void *unused)
+{
+ dev_ops_remove_all(&bpf_ops);
+ devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(bpf));
}
SYSINIT(bpfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bpf_drvinit,NULL)
+SYSUNINIT(bpfdev, SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bpf_drvuninit, NULL);
#else /* !BPF */
/*
__BEGIN_DECLS
+#define BPF_MAX_CLONES 128
+
/* BSD style release date */
#define BPF_RELEASE 199606
pf_dev = make_dev(&pf_ops, 0, 0, 0, 0600, PF_NAME);
error = pfattach();
if (error) {
- dev_ops_remove(&pf_ops, 0, 0);
+ dev_ops_remove_all(&pf_ops);
return (error);
}
return (0);
pf_osfp_flush();
pf_osfp_cleanup();
cleanup_pf_zone();
- dev_ops_remove(&pf_ops, 0, 0);
+ dev_ops_remove_all(&pf_ops);
return 0;
}
return (EBUSY);
if_clone_detach(&tap_cloner);
- dev_ops_remove(&tap_ops, 0, 0);
+ dev_ops_remove_all(&tap_ops);
/* Maintain tap ifs in a local list */
SLIST_FOREACH_MUTABLE(tp, &tap_listhead, tap_link, ntp)
smb_iod_done();
error = smb_sm_done();
error = 0;
- dev_ops_remove(&nsmb_ops, 0, 0);
+ //dev_ops_remove(&nsmb_ops, 0, 0);
+ dev_ops_remove_all(&nsmb_ops);
kprintf("netsmb_dev: unloaded\n");
break;
default:
return 0;
case MOD_UNLOAD:
/*XXX disallow if active sessions */
- dev_ops_remove(&crypto_ops, 0, 0);
+ //dev_ops_remove(&crypto_ops, 0, 0);
+ dev_ops_remove_all(&crypto_ops);
return 0;
}
return EINVAL;
int error;
tp = dev->si_tty = ttymalloc(dev->si_tty);
+ kprintf("vcons_open(): called! (tty: %x, dev: %x)\n", tp, dev);
+
+#define ISSET(t, f) ((t) & (f))
+ if (!ISSET(tp->t_state, TS_ISOPEN)) {
+ kprintf("vcons_open(): Verified, tty is *NOT* open\n");
+ } else {
+ kprintf("vcons_open(): Verified, tty is open\n");
+ }
if ((tp->t_state & TS_ISOPEN) == 0) {
tp->t_oproc = vcons_tty_start;
tp->t_param = vcons_tty_param;
tp->t_dev = dev;
tp->t_state |= TS_CARR_ON | TS_CONNECTED;
+ kprintf("vcons_open(): ttyv (%x) is TS_CONNECTED\n", tp);
ttychars(tp);
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
*/
dev_ops_add(&vcons_ops, -1 & ~7, 0);
for (i = 0; i < 8; ++i) {
+ kprintf("vconsinit_fini(): make_dev for ttyv%d\n", i);
dev = make_dev(&vcons_ops, i,
UID_ROOT, GID_WHEEL, 0600, "ttyv%d", i);
- if (i == 0)
+ kprintf("dev is: %x\n", dev);
+ if (i == 0) {
cp->cn_dev = dev;
+ kprintf("dev0 is: %x\n", dev);
+ }
}
EVENTHANDLER_REGISTER(shutdown_final, vconscleanup, NULL, SHUTDOWN_PRI_LAST);
}
struct cdev {
u_int si_flags;
- __uint64_t si_inode;
- uid_t si_uid;
- gid_t si_gid;
- int si_perms;
+ __uint64_t si_inode;
+ uid_t si_uid;
+ gid_t si_gid;
+ int si_perms;
TAILQ_ENTRY(cdev) link;
int si_uminor;
int si_umajor;
#define SI_HASHED 0x0002 /* in (maj,min) hash table */
#define SI_ADHOC 0x0004 /* created via make_adhoc_dev() or udev2dev() */
#define SI_INTERCEPTED 0x0008 /* device ops was intercepted */
+#define SI_DEVFS_LINKED 0x0010
#define si_tty __si_u.__si_tty.__sit_tty
#define si_disk __si_u.__si_disk.__sid_disk
short cn_probegood; /* probe routine must set to non-zero */
void *cn_private; /* private data for get/check/put/dbctl */
void *cn_gdbprivate; /* private data for gdb */
+ int cn_unit; /* some drivers prefer this */
+ int cn_flags; /* capabilities of this console */
+ //char cn_name[SPECNAMELEN + 1]; /* console (device) name */
+
};
+/* Values for cn_flags. */
+#define CN_FLAG_NODEBUG 0x00000001 /* Not supported with debugger. */
+#define CN_FLAG_NOAVAIL 0x00000002 /* Temporarily not available. */
+
+
/* values for cn_pri - reflect our policy for console selection */
#define CN_DEAD 0 /* device doesn't exist */
#define CN_NORMAL 1 /* device exists but is nothing special */
#endif
struct cdev;
+struct ucred;
/*
* This structure is at the base of every device args structure
*/
struct dev_clone_args {
struct dev_generic_args a_head;
+ struct cdev *a_dev;
+ struct ucred *a_cred;
+
+ char *a_name;
+ size_t a_namelen;
};
/*
extern struct syslink_desc dev_clone_desc;
void compile_dev_ops(struct dev_ops *);
-int dev_ops_scan(int (*callback)(struct dev_ops *, void *), void *arg);
int dev_ops_add(struct dev_ops *, u_int mask, u_int match);
int dev_ops_remove(struct dev_ops *, u_int mask, u_int match);
+int dev_ops_remove_all(struct dev_ops *ops);
+int dev_ops_remove_minor(struct dev_ops *ops, int minor);
void dev_ops_release(struct dev_ops *);
-struct dev_ops *dev_ops_add_override(cdev_t, struct dev_ops *, u_int, u_int);
-void dev_ops_remove_override(struct dev_ops *ops, u_int mask, u_int match);
-
struct dev_ops *dev_ops_intercept(cdev_t, struct dev_ops *);
void dev_ops_restore(cdev_t, struct dev_ops *);
struct dev_ops *dev_ops_get(int x, int y);
cdev_t make_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
int perms, const char *fmt, ...) __printflike(6, 7);
cdev_t make_adhoc_dev (struct dev_ops *ops, int minor);
-
+cdev_t make_only_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
+ int perms, const char *fmt, ...) __printflike(6, 7);
+cdev_t make_only_devfs_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid,
+ int perms, const char *fmt, ...) __printflike(6, 7);
+void destroy_only_dev(cdev_t dev);
+int make_dev_alias(cdev_t target, const char *fmt, ...);
#endif
#endif
#ifndef _SYS_QUEUE_H_
#include <sys/queue.h>
#endif
+#ifndef _SYS_MSGPORT_H_
+#include <sys/msgport.h>
+#endif
/*
* Media information structure - filled in by the media driver.
int disk_dumpcheck (cdev_t dev, u_int64_t *count, u_int64_t *blkno, u_int *secsize);
struct disk *disk_enumerate (struct disk *disk);
void disk_invalidate (struct disk *disk);
+
+
+void disk_msg_send(uint32_t cmd, void *load, void *load2);
+void disk_config(void *);
+
+typedef struct disk_msg {
+ struct lwkt_msg hdr;
+
+ void *load;
+ void *load2;
+} *disk_msg_t;
+
+#define DISK_DISK_PROBE 0x01
+#define DISK_DISK_DESTROY 0x02
+#define DISK_SLICE_REPROBE 0x03
+#define DISK_DISK_REPROBE 0x04
+#define DISK_SYNC 0x99
+
+
#endif /* _KERNEL */
#endif /* _SYS_DISK_H_ */
* no label present.
*/
struct diskslice {
+#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
+ cdev_t ds_dev;
+#else
+ void *ds_dev;
+#endif
u_int64_t ds_offset; /* starting sector */
u_int64_t ds_size; /* number of sectors */
u_int32_t ds_reserved; /* sectors reserved parent overlap */
int ds_type; /* (foreign) slice type */
disklabel_t ds_label; /* label, if any */
struct disklabel_ops *ds_ops; /* label ops (probe default) */
- void *ds_dev; /* devfs token for raw whole slice */
+ //void *ds_dev; /* devfs token for raw whole slice */
void *ds_devs[MAXPARTITIONS]; /* XXX s.b. in label */
u_int32_t ds_openmask[DKMAXPARTITIONS/(sizeof(u_int32_t)*8)];
/* devs open */
#include <sys/ioccom.h>
+struct fiodname_args {
+ void *name;
+ unsigned int len;
+};
+
/* Generic file-descriptor ioctl's. */
#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
#define FIONCLEX _IO('f', 2) /* remove close on exec */
#define FIOGETOWN _IOR('f', 123, int) /* get owner */
#define FIODTYPE _IOR('f', 122, int) /* get d_flags type part */
#define FIOGETLBA _IOR('f', 121, int) /* get start blk # */
-
+#define FIODNAME _IOW('f', 120, struct fiodname_args) /* get name of device on that fildesc */
#endif /* !_SYS_FILIO_H_ */
VT_PORTAL, VT_NULL, VT_UNUSED10, VT_KERNFS, VT_PROCFS, VT_AFS,
VT_ISOFS, VT_UNION, VT_MSDOSFS, VT_TFS, VT_VFS, VT_CODA, VT_NTFS,
VT_HPFS, VT_NWFS, VT_SMBFS, VT_UDF, VT_EXT2FS, VT_SYNTH,
- VT_USERFS, VT_HAMMER
+ VT_USERFS, VT_HAMMER, VT_DEVFS
};
/*
if (vp->v_type != VCHR)
panic("mfs_open not VCHR");
- v_associate_rdev(vp, get_dev(vp->v_umajor, vp->v_uminor));
+
+ vp->v_rdev = NULL;
+ //v_associate_rdev(vp, get_dev(vp->v_umajor, vp->v_uminor));
return (vop_stdopen(ap));
}