1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27/*
28 * Ramdisk device driver.
29 *
30 * There are two types of ramdisk: 'real' OBP-created ramdisks, and 'pseudo'
31 * ramdisks created at runtime with no corresponding OBP device node.  The
32 * ramdisk(7D) driver is capable of dealing with both, and with the creation
33 * and deletion of 'pseudo' ramdisks.
34 *
35 * Every ramdisk has a single 'state' structure which maintains data for
36 * that ramdisk, and is assigned a single minor number.  The bottom 10-bits
37 * of the minor number index the state structures; the top 8-bits give a
38 * 'real OBP disk' number, i.e. they are zero for 'pseudo' ramdisks.  Thus
39 * it is possible to distinguish 'real' from 'pseudo' ramdisks using the
40 * top 8-bits of the minor number.
41 *
42 * Each OBP-created ramdisk has its own node in the device tree with an
43 * "existing" property which describes the one-or-more physical address ranges
44 * assigned to the ramdisk.  All 'pseudo' ramdisks share a common devinfo
45 * structure.
46 *
47 * A single character device node is used by ramdiskadm(1M) to communicate
48 * with the ramdisk driver, with minor number 0:
49 *
50 *	/dev/ramdiskctl -> /devices/pseudo/ramdisk@0:ctl
51 *
52 * For consistent access, block and raw device nodes are created for *every*
53 * ramdisk.  For 'pseudo' ramdisks:
54 *
55 *	/dev/ramdisk/<diskname>  -> /devices/pseudo/ramdisk@0:<diskname>
56 *	/dev/rramdisk/<diskname> -> /devices/pseudo/ramdisk@0:<diskname>,raw
57 *
58 * For OBP-created ramdisks:
59 *
60 *	/dev/ramdisk/<diskname>  -> /devices/ramdisk-<diskname>:a
61 *	/dev/ramdisk/<diskname>  -> /devices/ramdisk-<diskname>:a,raw
62 *
63 * This allows the transition from the standalone to the kernel to proceed
64 * when booting from a ramdisk, and for the installation to correctly identify
65 * the root device.
66 */
67
68#include <sys/types.h>
69#include <sys/param.h>
70#include <sys/sysmacros.h>
71#include <sys/errno.h>
72#include <sys/uio.h>
73#include <sys/buf.h>
74#include <sys/modctl.h>
75#include <sys/open.h>
76#include <sys/kmem.h>
77#include <sys/poll.h>
78#include <sys/conf.h>
79#include <sys/cmn_err.h>
80#include <sys/stat.h>
81#include <sys/file.h>
82#include <sys/ddi.h>
83#include <sys/sunddi.h>
84#include <sys/ramdisk.h>
85#include <vm/seg_kmem.h>
86
87/*
88 * Flag to disable the use of real ramdisks (in the OBP - on Sparc) when
89 * the associated memory is no longer available - set in the bootops section.
90 */
91#ifdef __sparc
92extern int bootops_obp_ramdisk_disabled;
93#endif /* __sparc */
94
95/*
96 * An opaque handle where information about our set of ramdisk devices lives.
97 */
98static void	*rd_statep;
99
100/*
101 * Pointer to devinfo for the 'pseudo' ramdisks.  Real OBP-created ramdisks
102 * get their own individual devinfo.
103 */
104static dev_info_t *rd_dip = NULL;
105
106/*
107 * Global state lock.
108 */
109static kmutex_t	rd_lock;
110
111/*
112 * Maximum number of ramdisks supported by this driver.
113 */
114static uint32_t	rd_max_disks = RD_DFLT_DISKS;
115
116/*
117 * Percentage of physical memory which can be assigned to pseudo ramdisks,
118 * what that equates to in pages, and how many pages are currently assigned.
119 */
120static uint_t	rd_percent_physmem = RD_DEFAULT_PERCENT_PHYSMEM;
121static pgcnt_t	rd_max_physmem;
122static pgcnt_t	rd_tot_physmem;
123
124static uint_t	rd_maxphys = RD_DEFAULT_MAXPHYS;
125
126/*
127 * Is the driver busy, i.e. are there any pseudo ramdisk devices in existence?
128 */
129static int
130rd_is_busy(void)
131{
132	minor_t	minor;
133	rd_devstate_t	*rsp;
134
135	ASSERT(mutex_owned(&rd_lock));
136	for (minor = 1; minor <= rd_max_disks; ++minor) {
137		if ((rsp = ddi_get_soft_state(rd_statep, minor)) != NULL &&
138		    rsp->rd_dip == rd_dip) {
139			return (EBUSY);
140		}
141	}
142	return (0);
143}
144
145/*
146 * Find the first free minor number; returns zero if there isn't one.
147 */
148static minor_t
149rd_find_free_minor(void)
150{
151	minor_t	minor;
152
153	ASSERT(mutex_owned(&rd_lock));
154	for (minor = 1; minor <= rd_max_disks; ++minor) {
155		if (ddi_get_soft_state(rd_statep, minor) == NULL) {
156			return (minor);
157		}
158	}
159	return (0);
160}
161
162/*
163 * Locate the rd_devstate for the named ramdisk; returns NULL if not found.
164 * Each ramdisk is identified uniquely by name, i.e. an OBP-created ramdisk
165 * cannot have the same name as a pseudo ramdisk.
166 */
167static rd_devstate_t *
168rd_find_named_disk(char *name)
169{
170	minor_t		minor;
171	rd_devstate_t	*rsp;
172
173	ASSERT(mutex_owned(&rd_lock));
174	for (minor = 1; minor <= rd_max_disks; ++minor) {
175		if ((rsp = ddi_get_soft_state(rd_statep, minor)) != NULL &&
176		    strcmp(rsp->rd_name, name) == 0) {
177			return (rsp);
178		}
179	}
180	return (NULL);
181}
182
183/*
184 * Locate the rd_devstate for the real OBP-created ramdisk whose devinfo
185 * is referenced by 'dip'; returns NULL if not found (shouldn't happen).
186 */
187static rd_devstate_t *
188rd_find_dip_state(dev_info_t *dip)
189{
190	minor_t		minor;
191	rd_devstate_t	*rsp;
192
193	ASSERT(mutex_owned(&rd_lock));
194	for (minor = 1; minor <= rd_max_disks; ++minor) {
195		if ((rsp = ddi_get_soft_state(rd_statep, minor)) != NULL &&
196		    rsp->rd_dip == dip) {
197			return (rsp);
198		}
199	}
200	return (NULL);
201}
202
203/*
204 * Is the ramdisk open?
205 */
206static int
207rd_is_open(rd_devstate_t *rsp)
208{
209	ASSERT(mutex_owned(&rd_lock));
210	return (rsp->rd_chr_open || rsp->rd_blk_open || rsp->rd_lyr_open_cnt);
211}
212
213/*
214 * Mark the ramdisk open.
215 */
216static int
217rd_opened(rd_devstate_t *rsp, int otyp)
218{
219	ASSERT(mutex_owned(&rd_lock));
220	switch (otyp) {
221	case OTYP_CHR:
222		rsp->rd_chr_open = 1;
223		break;
224	case OTYP_BLK:
225		rsp->rd_blk_open = 1;
226		break;
227	case OTYP_LYR:
228		rsp->rd_lyr_open_cnt++;
229		break;
230	default:
231		return (-1);
232	}
233	return (0);
234}
235
236/*
237 * Mark the ramdisk closed.
238 */
239static void
240rd_closed(rd_devstate_t *rsp, int otyp)
241{
242	ASSERT(mutex_owned(&rd_lock));
243	switch (otyp) {
244	case OTYP_CHR:
245		rsp->rd_chr_open = 0;
246		break;
247	case OTYP_BLK:
248		rsp->rd_blk_open = 0;
249		break;
250	case OTYP_LYR:
251		rsp->rd_lyr_open_cnt--;
252		break;
253	default:
254		break;
255	}
256}
257
258static void
259rd_init_tuneables(void)
260{
261	char	*prop, *p;
262
263	/*
264	 * Ensure sanity of 'rd_max_disks', which may be tuned in ramdisk.conf.
265	 */
266	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, rd_dip, 0,
267	    "max_disks", &prop) == DDI_PROP_SUCCESS) {
268		p = prop;
269		rd_max_disks = (uint32_t)stoi(&p);
270		ddi_prop_free(prop);
271	}
272	if (rd_max_disks >= RD_MAX_DISKS) {
273		cmn_err(CE_WARN, "ramdisk: rd_max_disks (%u) too big;"
274		    " using default (%u).", rd_max_disks, RD_MAX_DISKS - 1);
275
276		rd_max_disks = RD_MAX_DISKS - 1;
277	}
278
279	/*
280	 * Ensure sanity of 'rd_percent_physmem', which may be tuned
281	 * in ramdisk.conf.
282	 */
283	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, rd_dip, 0,
284	    "percent_physmem", &prop) == DDI_PROP_SUCCESS) {
285		p = prop;
286		rd_percent_physmem = (uint_t)stoi(&p);
287		ddi_prop_free(prop);
288	}
289	if (rd_percent_physmem >= 100) {
290		cmn_err(CE_WARN, "ramdisk: rd_percent_physmem (%u) >= 100;"
291		    " using default (%u%%).", rd_percent_physmem,
292		    RD_DEFAULT_PERCENT_PHYSMEM);
293
294		rd_percent_physmem = RD_DEFAULT_PERCENT_PHYSMEM;
295	}
296
297	/*
298	 * Since availrmem_initial is a long, this won't overflow.
299	 */
300	rd_max_physmem = (availrmem_initial * rd_percent_physmem) / 100;
301}
302
303/*
304 * Allocate enough physical pages to hold "npages" pages.  Returns an
305 * array of page_t * pointers that can later be mapped in or out via
306 * rd_{un}map_window() but is otherwise opaque, or NULL on failure.
307 */
308page_t **
309rd_phys_alloc(pgcnt_t npages)
310{
311	page_t		*pp, **ppa;
312	spgcnt_t	i;
313	size_t		ppalen;
314	struct seg	kseg;
315	caddr_t		addr;		/* For coloring */
316
317	if (rd_tot_physmem + npages > rd_max_physmem)
318		return (NULL);
319
320	if (!page_resv(npages, KM_NOSLEEP))
321		return (NULL);
322
323	if (!page_create_wait(npages, 0)) {
324		page_unresv(npages);
325		return (NULL);
326	}
327
328	ppalen = npages * sizeof (struct page_t *);
329	ppa = kmem_zalloc(ppalen, KM_NOSLEEP);
330	if (ppa == NULL) {
331		page_create_putback(npages);
332		page_unresv(npages);
333		return (NULL);
334	}
335
336	kseg.s_as = &kas;
337	for (i = 0, addr = NULL; i < npages; ++i, addr += PAGESIZE) {
338		pp = page_get_freelist(&kvp, 0, &kseg, addr, PAGESIZE, 0, NULL);
339		if (pp == NULL) {
340			pp = page_get_cachelist(&kvp, 0, &kseg, addr, 0, NULL);
341			if (pp == NULL)
342				goto out;
343			if (!PP_ISAGED(pp))
344				page_hashout(pp, NULL);
345		}
346
347		PP_CLRFREE(pp);
348		PP_CLRAGED(pp);
349		ppa[i] = pp;
350	}
351
352	for (i = 0; i < npages; i++)
353		page_downgrade(ppa[i]);
354	rd_tot_physmem += npages;
355
356	return (ppa);
357
358out:
359	ASSERT(i < npages);
360	page_create_putback(npages - i);
361	while (--i >= 0)
362		page_free(ppa[i], 0);
363	kmem_free(ppa, ppalen);
364	page_unresv(npages);
365
366	return (NULL);
367}
368
369/*
370 * Free physical pages previously allocated via rd_phys_alloc(); note that
371 * this function may block as it has to wait until it can exclusively lock
372 * all the pages first.
373 */
374static void
375rd_phys_free(page_t **ppa, pgcnt_t npages)
376{
377	pgcnt_t	i;
378	size_t	ppalen = npages * sizeof (struct page_t *);
379
380	for (i = 0; i < npages; ++i) {
381		if (! page_tryupgrade(ppa[i])) {
382			page_unlock(ppa[i]);
383			while (! page_lock(ppa[i], SE_EXCL, NULL, P_RECLAIM))
384				;
385		}
386		page_free(ppa[i], 0);
387	}
388
389	kmem_free(ppa, ppalen);
390
391	page_unresv(npages);
392	rd_tot_physmem -= npages;
393}
394
395/*
396 * Remove a window mapping (if present).
397 */
398static void
399rd_unmap_window(rd_devstate_t *rsp)
400{
401	ASSERT(rsp->rd_window_obp == 0);
402	if (rsp->rd_window_base != RD_WINDOW_NOT_MAPPED) {
403		hat_unload(kas.a_hat, rsp->rd_window_virt, rsp->rd_window_size,
404		    HAT_UNLOAD_UNLOCK);
405	}
406}
407
408/*
409 * Map a portion of the ramdisk into the virtual window.
410 */
411static void
412rd_map_window(rd_devstate_t *rsp, off_t offset)
413{
414	pgcnt_t	offpgs = btop(offset);
415
416	if (rsp->rd_window_base != RD_WINDOW_NOT_MAPPED) {
417		/*
418		 * Already mapped; is offset within our window?
419		 */
420		if (offset >= rsp->rd_window_base &&
421		    offset < rsp->rd_window_base + rsp->rd_window_size) {
422			return;
423		}
424
425		/*
426		 * No, we need to re-map; toss the old mapping.
427		 */
428		rd_unmap_window(rsp);
429	}
430	rsp->rd_window_base = ptob(offpgs);
431
432	/*
433	 * Different algorithms depending on whether this is a real
434	 * OBP-created ramdisk, or a pseudo ramdisk.
435	 */
436	if (rsp->rd_dip == rd_dip) {
437		pgcnt_t	pi, lastpi;
438		caddr_t	vaddr;
439
440		/*
441		 * Find the range of pages which should be mapped.
442		 */
443		pi = offpgs;
444		lastpi = pi + btopr(rsp->rd_window_size);
445		if (lastpi > rsp->rd_npages) {
446			lastpi = rsp->rd_npages;
447		}
448
449		/*
450		 * Load the mapping.
451		 */
452		vaddr = rsp->rd_window_virt;
453		for (; pi < lastpi; ++pi) {
454			hat_memload(kas.a_hat, vaddr, rsp->rd_ppa[pi],
455			    (PROT_READ | PROT_WRITE) | HAT_NOSYNC,
456			    HAT_LOAD_LOCK);
457			vaddr += ptob(1);
458		}
459	} else {
460		uint_t	i;
461		pfn_t	pfn;
462
463		/*
464		 * Real OBP-created ramdisk: locate the physical range which
465		 * contains this offset.
466		 */
467		for (i = 0; i < rsp->rd_nexisting; ++i) {
468			if (offset < rsp->rd_existing[i].size) {
469				break;
470			}
471			offset -= rsp->rd_existing[i].size;
472		}
473		ASSERT(i < rsp->rd_nexisting);
474
475		/*
476		 * Load the mapping.
477		 */
478		pfn = btop(rsp->rd_existing[i].phys + offset);
479		hat_devload(kas.a_hat, rsp->rd_window_virt, rsp->rd_window_size,
480		    pfn, (PROT_READ | PROT_WRITE),
481		    HAT_LOAD_NOCONSIST | HAT_LOAD_LOCK);
482	}
483}
484
485/*
486 * Fakes up a disk geometry, and one big partition, based on the size
487 * of the file. This is needed because we allow newfs'ing the device,
488 * and newfs will do several disk ioctls to figure out the geometry and
489 * partition information. It uses that information to determine the parameters
490 * to pass to mkfs. Geometry is pretty much irrelevant these days, but we
491 * have to support it.
492 *
493 * Stolen from lofi.c - should maybe split out common code sometime.
494 */
495static void
496rd_fake_disk_geometry(rd_devstate_t *rsp)
497{
498	/* dk_geom - see dkio(7I) */
499	/*
500	 * dkg_ncyl _could_ be set to one here (one big cylinder with gobs
501	 * of sectors), but that breaks programs like fdisk which want to
502	 * partition a disk by cylinder. With one cylinder, you can't create
503	 * an fdisk partition and put pcfs on it for testing (hard to pick
504	 * a number between one and one).
505	 *
506	 * The cheezy floppy test is an attempt to not have too few cylinders
507	 * for a small file, or so many on a big file that you waste space
508	 * for backup superblocks or cylinder group structures.
509	 */
510	if (rsp->rd_size < (2 * 1024 * 1024)) /* floppy? */
511		rsp->rd_dkg.dkg_ncyl = rsp->rd_size / (100 * 1024);
512	else
513		rsp->rd_dkg.dkg_ncyl = rsp->rd_size / (300 * 1024);
514	/* in case file file is < 100k */
515	if (rsp->rd_dkg.dkg_ncyl == 0)
516		rsp->rd_dkg.dkg_ncyl = 1;
517	rsp->rd_dkg.dkg_acyl = 0;
518	rsp->rd_dkg.dkg_bcyl = 0;
519	rsp->rd_dkg.dkg_nhead = 1;
520	rsp->rd_dkg.dkg_obs1 = 0;
521	rsp->rd_dkg.dkg_intrlv = 0;
522	rsp->rd_dkg.dkg_obs2 = 0;
523	rsp->rd_dkg.dkg_obs3 = 0;
524	rsp->rd_dkg.dkg_apc = 0;
525	rsp->rd_dkg.dkg_rpm = 7200;
526	rsp->rd_dkg.dkg_pcyl = rsp->rd_dkg.dkg_ncyl + rsp->rd_dkg.dkg_acyl;
527	rsp->rd_dkg.dkg_nsect = rsp->rd_size /
528	    (DEV_BSIZE * rsp->rd_dkg.dkg_ncyl);
529	rsp->rd_dkg.dkg_write_reinstruct = 0;
530	rsp->rd_dkg.dkg_read_reinstruct = 0;
531
532	/* vtoc - see dkio(7I) */
533	bzero(&rsp->rd_vtoc, sizeof (struct vtoc));
534	rsp->rd_vtoc.v_sanity = VTOC_SANE;
535	rsp->rd_vtoc.v_version = V_VERSION;
536	bcopy(RD_DRIVER_NAME, rsp->rd_vtoc.v_volume, 7);
537	rsp->rd_vtoc.v_sectorsz = DEV_BSIZE;
538	rsp->rd_vtoc.v_nparts = 1;
539	rsp->rd_vtoc.v_part[0].p_tag = V_UNASSIGNED;
540	rsp->rd_vtoc.v_part[0].p_flag = V_UNMNT;
541	rsp->rd_vtoc.v_part[0].p_start = (daddr_t)0;
542	/*
543	 * The partition size cannot just be the number of sectors, because
544	 * that might not end on a cylinder boundary. And if that's the case,
545	 * newfs/mkfs will print a scary warning. So just figure the size
546	 * based on the number of cylinders and sectors/cylinder.
547	 */
548	rsp->rd_vtoc.v_part[0].p_size = rsp->rd_dkg.dkg_pcyl *
549	    rsp->rd_dkg.dkg_nsect * rsp->rd_dkg.dkg_nhead;
550
551	/* dk_cinfo - see dkio(7I) */
552	bzero(&rsp->rd_ci, sizeof (struct dk_cinfo));
553	(void) strcpy(rsp->rd_ci.dki_cname, RD_DRIVER_NAME);
554	rsp->rd_ci.dki_ctype = DKC_MD;
555	rsp->rd_ci.dki_flags = 0;
556	rsp->rd_ci.dki_cnum = 0;
557	rsp->rd_ci.dki_addr = 0;
558	rsp->rd_ci.dki_space = 0;
559	rsp->rd_ci.dki_prio = 0;
560	rsp->rd_ci.dki_vec = 0;
561	(void) strcpy(rsp->rd_ci.dki_dname, RD_DRIVER_NAME);
562	rsp->rd_ci.dki_unit = 0;
563	rsp->rd_ci.dki_slave = 0;
564	rsp->rd_ci.dki_partition = 0;
565	/*
566	 * newfs uses this to set maxcontig. Must not be < 16, or it
567	 * will be 0 when newfs multiplies it by DEV_BSIZE and divides
568	 * it by the block size. Then tunefs doesn't work because
569	 * maxcontig is 0.
570	 */
571	rsp->rd_ci.dki_maxtransfer = 16;
572}
573
574/*
575 * Deallocate resources (virtual and physical, device nodes, structures)
576 * from a ramdisk.
577 */
578static void
579rd_dealloc_resources(rd_devstate_t *rsp)
580{
581	dev_info_t	*dip = rsp->rd_dip;
582	char		namebuf[RD_NAME_LEN + 5];
583	dev_t		fulldev;
584
585	if (rsp->rd_window_obp == 0 && rsp->rd_window_virt != NULL) {
586		if (rsp->rd_window_base != RD_WINDOW_NOT_MAPPED) {
587			rd_unmap_window(rsp);
588		}
589		vmem_free(heap_arena, rsp->rd_window_virt, rsp->rd_window_size);
590	}
591	mutex_destroy(&rsp->rd_device_lock);
592
593	if (rsp->rd_existing) {
594		ddi_prop_free(rsp->rd_existing);
595	}
596	if (rsp->rd_ppa != NULL) {
597		rd_phys_free(rsp->rd_ppa, rsp->rd_npages);
598	}
599
600	/*
601	 * Remove the block and raw device nodes.
602	 */
603	if (dip == rd_dip) {
604		(void) snprintf(namebuf, sizeof (namebuf), "%s",
605		    rsp->rd_name);
606		ddi_remove_minor_node(dip, namebuf);
607		(void) snprintf(namebuf, sizeof (namebuf), "%s,raw",
608		    rsp->rd_name);
609		ddi_remove_minor_node(dip, namebuf);
610	} else {
611		ddi_remove_minor_node(dip, "a");
612		ddi_remove_minor_node(dip, "a,raw");
613	}
614
615	/*
616	 * Remove the "Size" and "Nblocks" properties.
617	 */
618	fulldev = makedevice(ddi_driver_major(dip), rsp->rd_minor);
619	(void) ddi_prop_remove(fulldev, dip, SIZE_PROP_NAME);
620	(void) ddi_prop_remove(fulldev, dip, NBLOCKS_PROP_NAME);
621
622	if (rsp->rd_kstat) {
623		kstat_delete(rsp->rd_kstat);
624		mutex_destroy(&rsp->rd_kstat_lock);
625	}
626
627	ddi_soft_state_free(rd_statep, rsp->rd_minor);
628}
629
630/*
631 * Allocate resources (virtual and physical, device nodes, structures)
632 * to a ramdisk.
633 */
634static rd_devstate_t *
635rd_alloc_resources(char *name, uint_t addr, size_t size, dev_info_t *dip)
636{
637	minor_t		minor;
638	rd_devstate_t	*rsp;
639	char		namebuf[RD_NAME_LEN + 5];
640	dev_t		fulldev;
641	int64_t		Nblocks_prop_val;
642	int64_t		Size_prop_val;
643
644	minor = rd_find_free_minor();
645	if (ddi_soft_state_zalloc(rd_statep, minor) == DDI_FAILURE) {
646		return (NULL);
647	}
648	rsp = ddi_get_soft_state(rd_statep, minor);
649
650	(void) strcpy(rsp->rd_name, name);
651	rsp->rd_dip = dip;
652	rsp->rd_minor = minor;
653	rsp->rd_size = size;
654
655	/*
656	 * Allocate virtual window onto ramdisk.
657	 */
658	mutex_init(&rsp->rd_device_lock, NULL, MUTEX_DRIVER, NULL);
659	if (addr == 0) {
660		rsp->rd_window_obp = 0;
661		rsp->rd_window_base = RD_WINDOW_NOT_MAPPED;
662		rsp->rd_window_size = PAGESIZE;
663		rsp->rd_window_virt = vmem_alloc(heap_arena,
664		    rsp->rd_window_size, VM_SLEEP);
665		if (rsp->rd_window_virt == NULL) {
666			goto create_failed;
667		}
668	} else {
669		rsp->rd_window_obp = 1;
670		rsp->rd_window_base = 0;
671		rsp->rd_window_size = size;
672		rsp->rd_window_virt = (caddr_t)((ulong_t)addr);
673	}
674
675	/*
676	 * Allocate physical memory for non-OBP ramdisks.
677	 * Create pseudo block and raw device nodes.
678	 */
679	if (dip == rd_dip) {
680		rsp->rd_npages = btopr(size);
681		rsp->rd_ppa = rd_phys_alloc(rsp->rd_npages);
682		if (rsp->rd_ppa == NULL) {
683			goto create_failed;
684		}
685
686		/*
687		 * For non-OBP ramdisks the device nodes are:
688		 *
689		 *	/devices/pseudo/ramdisk@0:<diskname>
690		 *	/devices/pseudo/ramdisk@0:<diskname>,raw
691		 */
692		(void) snprintf(namebuf, sizeof (namebuf), "%s",
693		    rsp->rd_name);
694		if (ddi_create_minor_node(dip, namebuf, S_IFBLK, minor,
695		    DDI_PSEUDO, 0) == DDI_FAILURE) {
696			goto create_failed;
697		}
698		(void) snprintf(namebuf, sizeof (namebuf), "%s,raw",
699		    rsp->rd_name);
700		if (ddi_create_minor_node(dip, namebuf, S_IFCHR, minor,
701		    DDI_PSEUDO, 0) == DDI_FAILURE) {
702			goto create_failed;
703		}
704	} else {
705		/*
706		 * For OBP-created ramdisks the device nodes are:
707		 *
708		 *	/devices/ramdisk-<diskname>:a
709		 *	/devices/ramdisk-<diskname>:a,raw
710		 */
711		if (ddi_create_minor_node(dip, "a", S_IFBLK, minor,
712		    DDI_PSEUDO, 0) == DDI_FAILURE) {
713			goto create_failed;
714		}
715		if (ddi_create_minor_node(dip, "a,raw", S_IFCHR, minor,
716		    DDI_PSEUDO, 0) == DDI_FAILURE) {
717			goto create_failed;
718		}
719	}
720
721	/*
722	 * Create the "Size" and "Nblocks" properties.
723	 */
724	fulldev = makedevice(ddi_driver_major(dip), minor);
725	Size_prop_val = size;
726	if ((ddi_prop_update_int64(fulldev, dip,
727	    SIZE_PROP_NAME, Size_prop_val)) != DDI_PROP_SUCCESS) {
728		goto create_failed;
729	}
730	Nblocks_prop_val = size / DEV_BSIZE;
731	if ((ddi_prop_update_int64(fulldev, dip,
732	    NBLOCKS_PROP_NAME, Nblocks_prop_val)) != DDI_PROP_SUCCESS) {
733		goto create_failed;
734	}
735
736	/*
737	 * Allocate kstat stuff.
738	 */
739	rsp->rd_kstat = kstat_create(RD_DRIVER_NAME, minor, NULL,
740	    "disk", KSTAT_TYPE_IO, 1, 0);
741	if (rsp->rd_kstat) {
742		mutex_init(&rsp->rd_kstat_lock, NULL,
743		    MUTEX_DRIVER, NULL);
744		rsp->rd_kstat->ks_lock = &rsp->rd_kstat_lock;
745		kstat_install(rsp->rd_kstat);
746	}
747
748	rd_fake_disk_geometry(rsp);
749
750	return (rsp);
751
752create_failed:
753	/*
754	 * Cleanup.
755	 */
756	rd_dealloc_resources(rsp);
757
758	return (NULL);
759}
760
761/*
762 * Undo what we did in rd_attach, freeing resources and removing things which
763 * we installed.  The system framework guarantees we are not active with this
764 * devinfo node in any other entry points at this time.
765 */
766static int
767rd_common_detach(dev_info_t *dip)
768{
769	if (dip == rd_dip) {
770		/*
771		 * Pseudo node: can't detach if any pseudo ramdisks exist.
772		 */
773		if (rd_is_busy()) {
774			return (DDI_FAILURE);
775		}
776		ddi_soft_state_free(rd_statep, RD_CTL_MINOR);
777		rd_dip = NULL;
778	} else {
779		/*
780		 * A 'real' ramdisk; find the state and free resources.
781		 */
782		rd_devstate_t	*rsp;
783
784		if ((rsp = rd_find_dip_state(dip)) != NULL) {
785			rd_dealloc_resources(rsp);
786		}
787	}
788	ddi_remove_minor_node(dip, NULL);
789
790	return (DDI_SUCCESS);
791}
792
793static int
794rd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
795{
796	char		*name;
797	rd_existing_t	*ep = NULL;
798	uint_t		obpaddr = 0, nep, i;
799	size_t		size = 0;
800	rd_devstate_t	*rsp;
801
802	switch (cmd) {
803
804	case DDI_ATTACH:
805		mutex_enter(&rd_lock);
806
807		/*
808		 * For pseudo ramdisk devinfo set up state 0 and :ctl device;
809		 * else it's an OBP-created ramdisk.
810		 */
811		if (is_pseudo_device(dip)) {
812			rd_dip = dip;
813			rd_init_tuneables();
814
815			/*
816			 * The zeroth minor is reserved for the ramdisk
817			 * 'control' device.
818			 */
819			if (ddi_soft_state_zalloc(rd_statep, RD_CTL_MINOR) ==
820			    DDI_FAILURE) {
821				goto attach_failed;
822			}
823			rsp = ddi_get_soft_state(rd_statep, RD_CTL_MINOR);
824			rsp->rd_dip = dip;
825
826			if (ddi_create_minor_node(dip, RD_CTL_NODE,
827			    S_IFCHR, 0, DDI_PSEUDO, NULL) == DDI_FAILURE) {
828				goto attach_failed;
829			}
830		} else {
831#ifdef __sparc
832			if (bootops_obp_ramdisk_disabled)
833				goto attach_failed;
834#endif /* __sparc */
835
836			RD_STRIP_PREFIX(name, ddi_node_name(dip));
837
838			if (strlen(name) > RD_NAME_LEN) {
839				cmn_err(CE_CONT,
840				    "%s: name too long - ignoring\n", name);
841				goto attach_failed;
842			}
843
844			/*
845			 * An OBP-created ramdisk must have an 'existing'
846			 * property; get and check it.
847			 */
848			if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
849			    DDI_PROP_DONTPASS, OBP_EXISTING_PROP_NAME,
850			    (uchar_t **)&ep, &nep) == DDI_SUCCESS) {
851
852				if (nep == 0 || (nep % sizeof (*ep)) != 0) {
853					cmn_err(CE_CONT,
854					    "%s: " OBP_EXISTING_PROP_NAME
855					    " illegal size\n", name);
856					goto attach_failed;
857				}
858				nep /= sizeof (*ep);
859
860				/*
861				 * Calculate the size of the ramdisk.
862				 */
863				for (i = 0; i < nep; ++i) {
864					size += ep[i].size;
865				}
866			} else if ((obpaddr = ddi_prop_get_int(DDI_DEV_T_ANY,
867			    dip, DDI_PROP_DONTPASS, OBP_ADDRESS_PROP_NAME,
868			    0)) != 0)  {
869
870				size = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
871				    DDI_PROP_DONTPASS, OBP_SIZE_PROP_NAME, 0);
872			} else {
873				cmn_err(CE_CONT, "%s: missing OBP properties\n",
874				    name);
875				goto attach_failed;
876			}
877
878			/*
879			 * Allocate driver resources for the ramdisk.
880			 */
881			if ((rsp = rd_alloc_resources(name, obpaddr, size,
882			    dip)) == NULL) {
883				goto attach_failed;
884			}
885
886			rsp->rd_existing = ep;
887			rsp->rd_nexisting = nep;
888		}
889
890		mutex_exit(&rd_lock);
891
892		ddi_report_dev(dip);
893
894		return (DDI_SUCCESS);
895
896	case DDI_RESUME:
897		return (DDI_SUCCESS);
898
899	default:
900		return (DDI_FAILURE);
901	}
902
903attach_failed:
904	/*
905	 * Use our common detach routine to unallocate any stuff which
906	 * was allocated above.
907	 */
908	(void) rd_common_detach(dip);
909	mutex_exit(&rd_lock);
910
911	if (ep != NULL) {
912		ddi_prop_free(ep);
913	}
914	return (DDI_FAILURE);
915}
916
917static int
918rd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
919{
920	int	e;
921
922	switch (cmd) {
923
924	case DDI_DETACH:
925		mutex_enter(&rd_lock);
926		e = rd_common_detach(dip);
927		mutex_exit(&rd_lock);
928
929		return (e);
930
931	case DDI_SUSPEND:
932		return (DDI_SUCCESS);
933
934	default:
935		return (DDI_FAILURE);
936	}
937}
938
939/*ARGSUSED*/
940static int
941rd_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
942{
943	rd_devstate_t	*rsp;
944
945	switch (infocmd) {
946	case DDI_INFO_DEVT2DEVINFO:
947		if ((rsp = ddi_get_soft_state(rd_statep,
948		    getminor((dev_t)arg))) != NULL) {
949			*result = rsp->rd_dip;
950			return (DDI_SUCCESS);
951		}
952		*result = NULL;
953		return (DDI_FAILURE);
954
955	case DDI_INFO_DEVT2INSTANCE:
956		if ((rsp = ddi_get_soft_state(rd_statep,
957		    getminor((dev_t)arg))) != NULL) {
958			*result = (void *)(uintptr_t)
959			    ddi_get_instance(rsp->rd_dip);
960			return (DDI_SUCCESS);
961		}
962		*result = NULL;
963		return (DDI_FAILURE);
964
965	default:
966		return (DDI_FAILURE);
967	}
968}
969
970/*ARGSUSED3*/
971static int
972rd_open(dev_t *devp, int flag, int otyp, cred_t *credp)
973{
974	minor_t		minor;
975	rd_devstate_t	*rsp;
976
977	mutex_enter(&rd_lock);
978
979	minor = getminor(*devp);
980	if (minor == RD_CTL_MINOR) {
981		/*
982		 * Master control device; must be opened exclusively.
983		 */
984		if ((flag & FEXCL) != FEXCL || otyp != OTYP_CHR) {
985			mutex_exit(&rd_lock);
986			return (EINVAL);
987		}
988
989		rsp = ddi_get_soft_state(rd_statep, RD_CTL_MINOR);
990		if (rsp == NULL) {
991			mutex_exit(&rd_lock);
992			return (ENXIO);
993		}
994
995		if (rd_is_open(rsp)) {
996			mutex_exit(&rd_lock);
997			return (EBUSY);
998		}
999		(void) rd_opened(rsp, OTYP_CHR);
1000
1001		mutex_exit(&rd_lock);
1002
1003		return (0);
1004	}
1005
1006	rsp = ddi_get_soft_state(rd_statep, minor);
1007	if (rsp == NULL) {
1008		mutex_exit(&rd_lock);
1009		return (ENXIO);
1010	}
1011
1012	if (rd_opened(rsp, otyp) == -1) {
1013		mutex_exit(&rd_lock);
1014		return (EINVAL);
1015	}
1016
1017	mutex_exit(&rd_lock);
1018	return (0);
1019}
1020
1021/*ARGSUSED*/
1022static int
1023rd_close(dev_t dev, int flag, int otyp, struct cred *credp)
1024{
1025	minor_t		minor;
1026	rd_devstate_t	*rsp;
1027
1028	mutex_enter(&rd_lock);
1029
1030	minor = getminor(dev);
1031
1032	rsp = ddi_get_soft_state(rd_statep, minor);
1033	if (rsp == NULL) {
1034		mutex_exit(&rd_lock);
1035		return (EINVAL);
1036	}
1037
1038	rd_closed(rsp, otyp);
1039
1040	mutex_exit(&rd_lock);
1041
1042	return (0);
1043}
1044
1045static void
1046rd_minphys(struct buf *bp)
1047{
1048	if (bp->b_bcount > rd_maxphys) {
1049		bp->b_bcount = rd_maxphys;
1050	}
1051}
1052
1053static void
1054rd_rw(rd_devstate_t *rsp, struct buf *bp, offset_t offset, size_t nbytes)
1055{
1056	int	reading = bp->b_flags & B_READ;
1057	caddr_t	buf_addr;
1058
1059	bp_mapin(bp);
1060	buf_addr = bp->b_un.b_addr;
1061
1062	while (nbytes > 0) {
1063		offset_t	off_in_window;
1064		size_t		rem_in_window, copy_bytes;
1065		caddr_t		raddr;
1066
1067		mutex_enter(&rsp->rd_device_lock);
1068		rd_map_window(rsp, offset);
1069
1070		off_in_window = offset - rsp->rd_window_base;
1071		rem_in_window = rsp->rd_window_size - off_in_window;
1072
1073		raddr = rsp->rd_window_virt + off_in_window;
1074		copy_bytes = MIN(nbytes, rem_in_window);
1075
1076		if (reading) {
1077			(void) bcopy(raddr, buf_addr, copy_bytes);
1078		} else {
1079			(void) bcopy(buf_addr, raddr, copy_bytes);
1080		}
1081		mutex_exit(&rsp->rd_device_lock);
1082
1083		offset   += copy_bytes;
1084		buf_addr += copy_bytes;
1085		nbytes   -= copy_bytes;
1086	}
1087}
1088
1089/*
1090 * On Sparc, this function deals with both pseudo ramdisks and OBP ramdisks.
1091 * In the case where we freed the "bootarchive" ramdisk in bop_free_archive(),
1092 * we stop allowing access to the OBP ramdisks. To do so, we set the
1093 * bootops_obp_ramdisk_disabled flag to true, and we check if the operation
1094 * is for an OBP ramdisk. In this case we indicate an ENXIO error.
1095 */
1096static int
1097rd_strategy(struct buf *bp)
1098{
1099	rd_devstate_t	*rsp;
1100	offset_t	offset;
1101
1102	rsp = ddi_get_soft_state(rd_statep, getminor(bp->b_edev));
1103	offset = bp->b_blkno * DEV_BSIZE;
1104
1105#ifdef __sparc
1106	if (rsp == NULL ||
1107	    (bootops_obp_ramdisk_disabled &&
1108	    (rsp->rd_dip != rd_dip || rd_dip == NULL))) { /* OBP ramdisk */
1109#else /* __sparc */
1110	if (rsp == NULL) {
1111#endif /* __sparc */
1112		bp->b_error = ENXIO;
1113		bp->b_flags |= B_ERROR;
1114	} else if (offset >= rsp->rd_size) {
1115		bp->b_error = EINVAL;
1116		bp->b_flags |= B_ERROR;
1117	} else {
1118		size_t	nbytes;
1119
1120		if (rsp->rd_kstat) {
1121			mutex_enter(rsp->rd_kstat->ks_lock);
1122			kstat_runq_enter(KSTAT_IO_PTR(rsp->rd_kstat));
1123			mutex_exit(rsp->rd_kstat->ks_lock);
1124		}
1125
1126		nbytes = min(bp->b_bcount, rsp->rd_size - offset);
1127
1128		rd_rw(rsp, bp, offset, nbytes);
1129
1130		bp->b_resid = bp->b_bcount - nbytes;
1131
1132		if (rsp->rd_kstat) {
1133			kstat_io_t *kioptr;
1134
1135			mutex_enter(rsp->rd_kstat->ks_lock);
1136			kioptr = KSTAT_IO_PTR(rsp->rd_kstat);
1137			if (bp->b_flags & B_READ) {
1138				kioptr->nread += nbytes;
1139				kioptr->reads++;
1140			} else {
1141				kioptr->nwritten += nbytes;
1142				kioptr->writes++;
1143			}
1144			kstat_runq_exit(kioptr);
1145			mutex_exit(rsp->rd_kstat->ks_lock);
1146		}
1147	}
1148
1149	biodone(bp);
1150	return (0);
1151}
1152
1153/*ARGSUSED*/
1154static int
1155rd_read(dev_t dev, struct uio *uiop, cred_t *credp)
1156{
1157	rd_devstate_t	*rsp;
1158
1159	rsp = ddi_get_soft_state(rd_statep, getminor(dev));
1160
1161	if (uiop->uio_offset >= rsp->rd_size)
1162		return (EINVAL);
1163
1164	return (physio(rd_strategy, NULL, dev, B_READ, rd_minphys, uiop));
1165}
1166
1167/*ARGSUSED*/
1168static int
1169rd_write(dev_t dev, register struct uio *uiop, cred_t *credp)
1170{
1171	rd_devstate_t	*rsp;
1172
1173	rsp = ddi_get_soft_state(rd_statep, getminor(dev));
1174
1175	if (uiop->uio_offset >= rsp->rd_size)
1176		return (EINVAL);
1177
1178	return (physio(rd_strategy, NULL, dev, B_WRITE, rd_minphys, uiop));
1179}
1180
1181/*ARGSUSED*/
1182static int
1183rd_create_disk(dev_t dev, struct rd_ioctl *urip, int mode, int *rvalp)
1184{
1185	struct rd_ioctl	kri;
1186	size_t		size;
1187	rd_devstate_t	*rsp;
1188
1189	if (ddi_copyin(urip, &kri, sizeof (kri), mode) == -1) {
1190		return (EFAULT);
1191	}
1192
1193	kri.ri_name[RD_NAME_LEN] = '\0';
1194
1195	size = kri.ri_size;
1196	if (size == 0) {
1197		return (EINVAL);
1198	}
1199	size = ptob(btopr(size));
1200
1201	mutex_enter(&rd_lock);
1202
1203	if (rd_find_named_disk(kri.ri_name) != NULL) {
1204		mutex_exit(&rd_lock);
1205		return (EEXIST);
1206	}
1207
1208	rsp = rd_alloc_resources(kri.ri_name, 0, size, rd_dip);
1209	if (rsp == NULL) {
1210		mutex_exit(&rd_lock);
1211		return (EAGAIN);
1212	}
1213
1214	mutex_exit(&rd_lock);
1215
1216	return (ddi_copyout(&kri, urip, sizeof (kri), mode) == -1 ? EFAULT : 0);
1217}
1218
1219/*ARGSUSED*/
1220static int
1221rd_delete_disk(dev_t dev, struct rd_ioctl *urip, int mode)
1222{
1223	struct rd_ioctl	kri;
1224	rd_devstate_t	*rsp;
1225
1226	if (ddi_copyin(urip, &kri, sizeof (kri), mode) == -1) {
1227		return (EFAULT);
1228	}
1229
1230	kri.ri_name[RD_NAME_LEN] = '\0';
1231
1232	mutex_enter(&rd_lock);
1233
1234	rsp = rd_find_named_disk(kri.ri_name);
1235	if (rsp == NULL || rsp->rd_dip != rd_dip) {
1236		mutex_exit(&rd_lock);
1237		return (EINVAL);
1238	}
1239	if (rd_is_open(rsp)) {
1240		mutex_exit(&rd_lock);
1241		return (EBUSY);
1242	}
1243
1244	rd_dealloc_resources(rsp);
1245
1246	mutex_exit(&rd_lock);
1247
1248	return (0);
1249}
1250
1251/*ARGSUSED*/
1252static int
1253rd_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp)
1254{
1255	minor_t		minor;
1256	int		error;
1257	enum dkio_state	dkstate;
1258	rd_devstate_t	*rsp;
1259
1260	minor = getminor(dev);
1261
1262	/*
1263	 * Ramdisk ioctls only apply to the master device.
1264	 */
1265	if (minor == RD_CTL_MINOR) {
1266		struct rd_ioctl *rip = (struct rd_ioctl *)arg;
1267
1268		/*
1269		 * The query commands only need read-access - i.e., normal
1270		 * users are allowed to do those on the controlling device
1271		 * as long as they can open it read-only.
1272		 */
1273		switch (cmd) {
1274		case RD_CREATE_DISK:
1275			if ((mode & FWRITE) == 0)
1276				return (EPERM);
1277			return (rd_create_disk(dev, rip, mode, rvalp));
1278
1279		case RD_DELETE_DISK:
1280			if ((mode & FWRITE) == 0)
1281				return (EPERM);
1282			return (rd_delete_disk(dev, rip, mode));
1283
1284		default:
1285			return (EINVAL);
1286		}
1287	}
1288
1289	rsp = ddi_get_soft_state(rd_statep, minor);
1290	if (rsp == NULL) {
1291		return (ENXIO);
1292	}
1293
1294	/*
1295	 * These are for faking out utilities like newfs.
1296	 */
1297	switch (cmd) {
1298	case DKIOCGVTOC:
1299		switch (ddi_model_convert_from(mode & FMODELS)) {
1300		case DDI_MODEL_ILP32: {
1301			struct vtoc32 vtoc32;
1302
1303			vtoctovtoc32(rsp->rd_vtoc, vtoc32);
1304			if (ddi_copyout(&vtoc32, (void *)arg,
1305			    sizeof (struct vtoc32), mode))
1306				return (EFAULT);
1307			}
1308			break;
1309
1310		case DDI_MODEL_NONE:
1311			if (ddi_copyout(&rsp->rd_vtoc, (void *)arg,
1312			    sizeof (struct vtoc), mode))
1313				return (EFAULT);
1314			break;
1315		}
1316		return (0);
1317	case DKIOCINFO:
1318		error = ddi_copyout(&rsp->rd_ci, (void *)arg,
1319		    sizeof (struct dk_cinfo), mode);
1320		if (error)
1321			return (EFAULT);
1322		return (0);
1323	case DKIOCG_VIRTGEOM:
1324	case DKIOCG_PHYGEOM:
1325	case DKIOCGGEOM:
1326		error = ddi_copyout(&rsp->rd_dkg, (void *)arg,
1327		    sizeof (struct dk_geom), mode);
1328		if (error)
1329			return (EFAULT);
1330		return (0);
1331	case DKIOCSTATE:
1332		/* the file is always there */
1333		dkstate = DKIO_INSERTED;
1334		error = ddi_copyout(&dkstate, (void *)arg,
1335		    sizeof (enum dkio_state), mode);
1336		if (error)
1337			return (EFAULT);
1338		return (0);
1339	default:
1340		return (ENOTTY);
1341	}
1342}
1343
1344
1345static struct cb_ops rd_cb_ops = {
1346	rd_open,
1347	rd_close,
1348	rd_strategy,
1349	nodev,
1350	nodev,		/* dump */
1351	rd_read,
1352	rd_write,
1353	rd_ioctl,
1354	nodev,		/* devmap */
1355	nodev,		/* mmap */
1356	nodev,		/* segmap */
1357	nochpoll,	/* poll */
1358	ddi_prop_op,
1359	NULL,
1360	D_NEW | D_MP
1361};
1362
1363static struct dev_ops rd_ops = {
1364	DEVO_REV,
1365	0,
1366	rd_getinfo,
1367	nulldev,	/* identify */
1368	nulldev,	/* probe */
1369	rd_attach,
1370	rd_detach,
1371	nodev,		/* reset */
1372	&rd_cb_ops,
1373	(struct bus_ops *)0,
1374	NULL,
1375	ddi_quiesce_not_needed,		/* quiesce */
1376};
1377
1378
1379extern struct mod_ops mod_driverops;
1380
1381static struct modldrv modldrv = {
1382	&mod_driverops,
1383	"ramdisk driver",
1384	&rd_ops
1385};
1386
1387static struct modlinkage modlinkage = {
1388	MODREV_1,
1389	&modldrv,
1390	0
1391};
1392
1393int
1394_init(void)
1395{
1396	int e;
1397
1398	if ((e = ddi_soft_state_init(&rd_statep,
1399	    sizeof (rd_devstate_t), 0)) != 0) {
1400		return (e);
1401	}
1402
1403	mutex_init(&rd_lock, NULL, MUTEX_DRIVER, NULL);
1404
1405	if ((e = mod_install(&modlinkage)) != 0)  {
1406		mutex_destroy(&rd_lock);
1407		ddi_soft_state_fini(&rd_statep);
1408	}
1409
1410	return (e);
1411}
1412
1413int
1414_fini(void)
1415{
1416	int e;
1417
1418	if ((e = mod_remove(&modlinkage)) != 0)  {
1419		return (e);
1420	}
1421
1422	ddi_soft_state_fini(&rd_statep);
1423	mutex_destroy(&rd_lock);
1424
1425	return (e);
1426}
1427
1428int
1429_info(struct modinfo *modinfop)
1430{
1431	return (mod_info(&modlinkage, modinfop));
1432}
1433