cmlb.h revision 8863:94039d51dda4
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#ifndef _SYS_CMLB_H
27#define	_SYS_CMLB_H
28
29#ifdef	__cplusplus
30extern "C" {
31#endif
32
33#include <sys/dktp/fdisk.h>
34
35/*
36 * structure used for getting phygeom and virtgeom from target driver
37 */
38typedef struct cmlb_geom {
39	unsigned int    g_ncyl;
40	unsigned short  g_acyl;
41	unsigned short  g_nhead;
42	unsigned short  g_nsect;
43	unsigned short  g_secsize;
44	diskaddr_t	g_capacity;
45	unsigned short  g_intrlv;
46	unsigned short  g_rpm;
47} cmlb_geom_t;
48
49
50typedef struct tg_attribute {
51	int media_is_writable;
52} tg_attribute_t;
53
54
55
56/* bit definitions for alter_behavior passed to cmlb_attach */
57
58#define	CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT	0x00000001
59#define	CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8		0x00000002
60#define	CMLB_OFF_BY_ONE					0x00000004
61#define	CMLB_FAKE_LABEL_ONE_PARTITION			0x00000008
62#define	CMLB_INTERNAL_MINOR_NODES			0x00000010
63
64/* bit definitions of flag passed to cmlb_validate */
65#define	CMLB_SILENT					0x00000001
66
67/* version for tg_ops */
68#define	TG_DK_OPS_VERSION_0	0
69#define	TG_DK_OPS_VERSION_1	1
70
71/* definitions for cmd passed to tg_rdwr */
72#define	TG_READ			0
73#define	TG_WRITE		1
74
75/* definitions for cmd passed to tg_getinfo */
76#define	TG_GETPHYGEOM		1
77#define	TG_GETVIRTGEOM		2
78#define	TG_GETCAPACITY		3
79#define	TG_GETBLOCKSIZE		4
80#define	TG_GETATTR		5
81
82
83/*
84 * Ops vector including utility functions into target driver that cmlb uses.
85 */
86typedef struct cmlb_tg_ops {
87	int	tg_version;
88
89	/*
90	 * tg_rdwr:
91	 *	perform read/write on target device associated with devi.
92	 *
93	 * Arguments:
94	 *
95	 *	devi:		pointer to device's dev_info structure.
96	 *
97	 *	cmd:		operation to perform.
98	 *			Possible values: TG_READ, TG_WRITE
99	 *
100	 *	bufp:		pointer to allocated buffer for transfer
101	 *
102	 *	start_block:	starting block number to read/write (based on
103	 *			system blocksize, DEV_BSIZE)
104	 *
105	 *	reqlength:	requested transfer length (in bytes)
106	 *
107	 *	tg_cookie 	cookie from target driver to be passed back to
108	 *			target driver when we call back to it through
109	 *			tg_ops.
110	 *
111	 * Note: It is the responsibility of caller to make sure
112	 *	length of buffer pointed to by bufp is at least equal to
113	 *	requested transfer length
114	 *
115	 * Return values:
116	 *	0		success
117	 *	ENOMEM		can not allocate memory
118	 *	EACCESS  	reservation conflict
119	 *	EIO		I/O error
120	 *	EFAULT		copyin/copyout error
121	 *	ENXIO		internal error/ invalid devi
122	 *	EINVAL		invalid command value.
123	 */
124	int (*tg_rdwr)(dev_info_t *devi, uchar_t cmd, void *bufp,
125	    diskaddr_t start_block, size_t reqlength, void *tg_cookie);
126
127	/*
128	 * tg_getinfo:
129	 * 	Report the information requested on device/media and
130	 *	store the requested info in area pointed to by arg.
131	 *
132	 * Arguments:
133	 *	devi:		pointer to device's dev_info structure.
134	 *
135	 *	cmd:		operation to perform
136	 *
137	 *	arg:		arg for the operation for result.
138	 *
139	 *	tg_cookie 	cookie from target driver to be passed back to
140	 *			target driver when we call back to it through
141	 *			tg_ops.
142	 *
143	 * 	Possible commands and the interpretation of arg:
144	 *
145	 *	cmd:
146	 *		TG_GETPHYGEOM
147	 *			Obtain raw physical geometry from target,
148	 *			and store in structure pointed to by arg,
149	 *			a cmlb_geom_t structure.
150	 *
151	 * 		TG_GETVIRTGEOM:
152	 *			Obtain HBA geometry for the target and
153	 *			store in struct pointed to by arg,
154	 *			a cmlb_geom_t structure.
155	 *
156	 *		TG_GETCAPACITY:
157	 *			Report the capacity of the target (in system
158	 *			blocksize (DEV_BSIZE) and store in the
159	 *			space pointed to by arg, a diskaddr_t.
160	 *
161	 *		TG_GETBLOCKSIZE:
162	 *			Report the block size of the target
163	 *			in the space pointed to by arg, a uint32_t.
164	 *
165	 *		TG_GETATTR:
166	 * 			Report the information requested on
167	 *			device/media and store in area pointed to by
168	 *			arg, a tg_attribute_t structure.
169	 *			Return values:
170	 *
171	 * Return values:
172	 *	0		success
173	 *
174	 *	EACCESS		reservation conflict
175	 *
176	 *	ENXIO		internal error/invalid devi
177	 *
178	 *	EINVAL		When command is TG_GETPHYGEOM or
179	 *			TG_GETVIRTGEOM, or TG_GETATTR, this return code
180	 *			indicates the operation is not applicable to
181	 *			target.
182	 *			In case of TG_GETCAP, this return code
183	 *			indicates no media in the drive.
184	 *
185	 *	EIO		An error occurred during obtaining info
186	 *			from device/media.
187	 *
188	 *	ENOTSUP		In case of TG_GETCAP, target does not
189	 *			support getting capacity info.
190	 *
191	 *	ENOTTY		Unknown command.
192	 *
193	 *
194	 */
195	int (*tg_getinfo)(dev_info_t *devi, int cmd, void *arg,
196	    void *tg_cookie);
197
198} cmlb_tg_ops_t;
199
200
201typedef struct __cmlb_handle *cmlb_handle_t;
202
203/*
204 *
205 * Functions exported from cmlb
206 *
207 * Note: Most these functions can callback to target driver through the
208 * tg_ops functions. Target driver should consider this for synchronization.
209 * Any functions that may adjust minor nodes should be called when
210 * the target driver ensures it is safe to do so.
211 */
212
213/*
214 * cmlb_alloc_handle:
215 *
216 *	Allocates a handle.
217 *
218 * Arguments:
219 *	cmlbhandlep	pointer to handle
220 *
221 * Notes:
222 *	Allocates a handle and stores the allocated handle in the area
223 *	pointed to by cmlbhandlep
224 *
225 * Context:
226 *	Kernel thread only (can sleep).
227 */
228void
229cmlb_alloc_handle(cmlb_handle_t *cmlbhandlep);
230
231
232/*
233 * cmlb_attach:
234 *
235 *	Attach handle to device, create minor nodes for device.
236 *
237 *
238 * Arguments:
239 * 	devi		pointer to device's dev_info structure.
240 * 	tgopsp		pointer to array of functions cmlb can use to callback
241 *			to target driver.
242 *
243 *	device_type	Peripheral device type as defined in
244 *			scsi/generic/inquiry.h
245 *
246 *	is_removable	whether or not device is removable.
247 *
248 *	is_hotpluggable	whether or not device is hotpluggable.
249 *
250 *	node_type	minor node type (as used by ddi_create_minor_node)
251 *
252 *	alter_behavior
253 *			bit flags:
254 *
255 *			CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT: create
256 *			an alternate slice for the default label, if
257 *			device type is DTYPE_DIRECT an architectures default
258 *			label type is VTOC16.
259 *			Otherwise alternate slice will no be created.
260 *
261 *
262 *			CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8: report a default
263 *			geometry and label for DKIOCGGEOM and DKIOCGVTOC
264 *			on architecture with VTOC 8 label types.
265 *
266 * 			CMLB_OFF_BY_ONE: do the workaround for legacy off-by-
267 *			one bug in obtaining capacity (used for sd).
268 *
269 *
270 *	cmlbhandle	cmlb handle associated with device
271 *
272 *	tg_cookie 	cookie from target driver to be passed back to target
273 *			driver when we call back to it through tg_ops.
274 *
275 *			cmlb does not interpret the values. It is currently
276 *			used for sd to indicate whether retries are allowed
277 *			on commands or not. e.g when cmlb entries are called
278 *			from interrupt context on removable media, sd rather
279 *			not have retries done.
280 *
281 *
282 *
283 * Notes:
284 *	Assumes a default label based on capacity for non-removable devices.
285 *	If capacity > 1TB, EFI is assumed otherwise VTOC (default VTOC
286 *	for the architecture).
287 *	For removable devices, default label type is assumed to be VTOC
288 *	type. Create minor nodes based on a default label type.
289 *	Label on the media is not validated.
290 *	minor number consists of:
291 *		if _SUNOS_VTOC_8 is defined
292 *			lowest 3 bits is taken as partition number
293 *			the rest is instance number
294 *		if _SUNOS_VTOC_16 is defined
295 *			lowest 6 bits is taken as partition number
296 *			the rest is instance number
297 *
298 *
299 * Return values:
300 *	0 	Success
301 * 	ENXIO 	creating minor nodes failed.
302 *	EINVAL	invalid arg, unsupported tg_ops version
303 *
304 */
305int
306cmlb_attach(dev_info_t *devi, cmlb_tg_ops_t *tgopsp, int device_type,
307    boolean_t is_removable, boolean_t is_hotpluggable, char *node_type,
308    int alter_behavior, cmlb_handle_t cmlbhandle, void *tg_cookie);
309
310
311/*
312 * cmlb_validate:
313 *
314 *	Validates label.
315 *
316 * Arguments
317 *	cmlbhandle	cmlb handle associated with device.
318 *
319 * 	int 		flags
320 *			currently used for verbosity control.
321 *			CMLB_SILENT is the only current definition for it
322 *	tg_cookie 	cookie from target driver to be passed back to target
323 *			driver when we call back to it through tg_ops.
324 * Notes:
325 *	If new label type is different from the current, adjust minor nodes
326 *	accordingly.
327 *
328 * Return values:
329 *	0		success
330 *			Note: having fdisk but no solaris partition is assumed
331 *			success.
332 *
333 *	ENOMEM		memory allocation failed
334 *	EIO		i/o errors during read or get capacity
335 * 	EACCESS		reservation conflicts
336 * 	EINVAL		label was corrupt, or no default label was assumed
337 *	ENXIO		invalid handle
338 *
339 */
340int
341cmlb_validate(cmlb_handle_t cmlbhandle, int flags, void *tg_cookie);
342
343/*
344 * cmlb_invalidate:
345 *	Invalidate in core label data
346 *
347 * Arguments:
348 *	cmlbhandle	cmlb handle associated with device.
349 *	tg_cookie 	cookie from target driver to be passed back to target
350 *			driver when we call back to it through tg_ops.
351 */
352void
353cmlb_invalidate(cmlb_handle_t cmlbhandle, void *tg_cookie);
354
355
356
357/*
358 * cmlb_is_valid
359 *	 Get status on whether the incore label/geom data is valid
360 *
361 * Arguments:
362 *      cmlbhandle      cmlb handle associated with device.
363 *
364 * Return values:
365 *      TRUE if valid
366 *      FALSE otherwise.
367 *
368 */
369boolean_t
370cmlb_is_valid(cmlb_handle_t cmlbhandle);
371
372/*
373 * cmlb_partinfo:
374 *	Get partition info for specified partition number.
375 *
376 * Arguments:
377 *	cmlbhandle	cmlb handle associated with device.
378 *	part		partition number
379 *			driver when we call back to it through tg_ops.
380 *	nblocksp	pointer to number of blocks
381 *	startblockp	pointer to starting block
382 *	partnamep	pointer to name of partition
383 *	tagp		pointer to tag info
384 *	tg_cookie 	cookie from target driver to be passed back to target
385 *
386 * Notes:
387 *	If in-core label is not valid, this functions tries to revalidate
388 *	the label. If label is valid, it stores the total number of blocks
389 *	in this partition in the area pointed to by nblocksp, starting
390 *	block number in area pointed to by startblockp,  pointer to partition
391 *	name in area pointed to by partnamep, and tag value in area
392 *	pointed by tagp.
393 *	For EFI labels, tag value will be set to 0.
394 *
395 *	For all nblocksp, startblockp and partnamep, tagp, a value of NULL
396 *	indicates the corresponding info is not requested.
397 *
398 *
399 * Return values:
400 *	0	success
401 *	EINVAL  no valid label or requested partition number is invalid.
402 *
403 */
404int
405cmlb_partinfo(cmlb_handle_t cmlbhandle, int part, diskaddr_t *nblocksp,
406    diskaddr_t *startblockp, char **partnamep, uint16_t *tagp, void *tg_cookie);
407
408/*
409 * cmlb_efi_label_capacity:
410 *	Get capacity stored in EFI disk label.
411 *
412 * Arguments:
413 *	cmlbhandle	cmlb handle associated with device.
414 *	capacity	pointer to capacity stored in EFI disk label.
415 *	tg_cookie	cookie from target driver to be passed back to target
416 *			driver when we call back to it through tg_ops.
417 *
418 *
419 * Notes:
420 *	If in-core label is not valid, this functions tries to revalidate
421 *	the label. If label is valid and is an EFI label, it stores the capacity
422 *      in disk label in the area pointed to by capacity.
423 *
424 *
425 * Return values:
426 *	0	success
427 *	EINVAL  no valid EFI label or capacity is NULL.
428 *
429 */
430int
431cmlb_efi_label_capacity(cmlb_handle_t cmlbhandle, diskaddr_t *capacity,
432    void *tg_cookie);
433
434/*
435 * cmlb_ioctl:
436 * Ioctls for label handling will be handled by this function.
437 * These are:
438 *	DKIOCGGEOM
439 *	DKIOCSGEOM
440 *	DKIOCGAPART
441 *	DKIOCSAPART
442 *	DKIOCGVTOC
443 *	DKIOCGETEFI
444 *	DKIOCPARTITION
445 *	DKIOCSVTOC
446 * 	DKIOCSETEFI
447 *	DKIOCGMBOOT
448 *	DKIOCSMBOOT
449 *	DKIOCG_PHYGEOM
450 *	DKIOCG_VIRTGEOM
451 *	DKIOCPARTINFO
452 *
453 *
454 *   Arguments:
455 *	cmlbhandle 	handle associated with device.
456 *      cmd     	ioctl operation to be performed
457 *      arg     	user argument, contains data to be set or reference
458 *                      parameter for get
459 *	flag    	bit flag, indicating open settings, 32/64 bit type
460 *      cred_p  	user credential pointer (not currently used)
461 *	rval_p  	not currently used
462 *	tg_cookie 	cookie from target driver to be passed back to target
463 *			driver when we call back to it through tg_ops.
464 *
465 *
466 *
467 * Return values:
468 *	0
469 *	EINVAL
470 *	ENOTTY
471 *	ENXIO
472 *	EIO
473 *	EFAULT
474 *	ENOTSUP
475 *	EPERM
476 */
477int
478cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd,
479    intptr_t arg, int flag, cred_t *cred_p, int *rval_p, void *tg_cookie);
480
481/*
482 * cmlb_prop_op:
483 *	provide common label prop_op(9E) implementation that understands the
484 *	size(9p) properties.
485 *
486 * Arguments:
487 *	cmlbhandle	cmlb handle associated with device.
488 *	dev		See prop_op(9E)
489 *	dip		"
490 *	prop_op		"
491 *	mod_flags	"
492 *	name		"
493 *	valuep		"
494 *	lengthp		"
495 *	part		partition number
496 *	tg_cookie 	cookie from target driver to be passed back to target
497 */
498int
499cmlb_prop_op(cmlb_handle_t cmlbhandle,
500    dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
501    char *name, caddr_t valuep, int *lengthp, int part, void *tg_cookie);
502
503/*
504 * cmlb_get_devid_block:
505 *	 get the block number where device id is stored.
506 *
507 * Arguments:
508 *	cmlbhandle	cmlb handle associated with device.
509 *	devidblockp	pointer to block number.
510 *	tg_cookie 	cookie from target driver to be passed back to target
511 *			driver when we call back to it through tg_ops.
512 *
513 * Notes:
514 *	It stores the block number of device id in the area pointed to
515 *	by devidblockp.
516 *
517 * Return values:
518 *	0	success
519 *	EINVAL 	device id does not apply to current label type.
520 */
521int
522cmlb_get_devid_block(cmlb_handle_t cmlbhandle, diskaddr_t *devidblockp,
523    void *tg_cookie);
524
525
526/*
527 * cmlb_close:
528 *
529 * Close the device, revert to a default label minor node for the device,
530 * if it is removable.
531 *
532 * Arguments:
533 *	cmlbhandle	cmlb handle associated with device.
534 *
535 *	tg_cookie 	cookie from target driver to be passed back to target
536 *			driver when we call back to it through tg_ops.
537 * Return values:
538 *	0	Success
539 * 	ENXIO	Re-creating minor node failed.
540 */
541int
542cmlb_close(cmlb_handle_t cmlbhandle, void *tg_cookie);
543
544/*
545 * cmlb_detach:
546 *
547 * Invalidate in-core labeling data and remove all minor nodes for
548 * the device associate with handle.
549 *
550 * Arguments:
551 *	cmlbhandle	cmlb handle associated with device.
552 *	tg_cookie 	cookie from target driver to be passed back to target
553 *			driver when we call back to it through tg_ops.
554 *
555 */
556void
557cmlb_detach(cmlb_handle_t cmlbhandle, void *tg_cookie);
558
559/*
560 * cmlb_free_handle
561 *
562 *	Frees handle.
563 *
564 * Arguments:
565 *	cmlbhandlep	pointer to handle
566 *
567 */
568void
569cmlb_free_handle(cmlb_handle_t *cmlbhandlep);
570
571#ifdef	__cplusplus
572}
573#endif
574
575#endif /* _SYS_CMLB_H */
576