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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
24 * Copyright 2012 Alexey Zaytsev <alexey.zaytsev@gmail.com> All rights reserved.
25 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
26 */
27
28 #include <sys/types.h>
29 #include <sys/ksynch.h>
30 #include <sys/kmem.h>
31 #include <sys/file.h>
32 #include <sys/errno.h>
33 #include <sys/open.h>
34 #include <sys/buf.h>
35 #include <sys/uio.h>
36 #include <sys/aio_req.h>
37 #include <sys/cred.h>
38 #include <sys/modctl.h>
39 #include <sys/cmlb.h>
40 #include <sys/conf.h>
41 #include <sys/devops.h>
42 #include <sys/list.h>
43 #include <sys/sysmacros.h>
44 #include <sys/dkio.h>
45 #include <sys/vtoc.h>
46 #include <sys/scsi/scsi.h> /* for DTYPE_DIRECT */
47 #include <sys/kstat.h>
48 #include <sys/fs/dv_node.h>
49 #include <sys/ddi.h>
50 #include <sys/sunddi.h>
51 #include <sys/note.h>
52 #include <sys/blkdev.h>
53 #include <sys/scsi/impl/inquiry.h>
54
55 #define BD_MAXPART 64
56 #define BDINST(dev) (getminor(dev) / BD_MAXPART)
57 #define BDPART(dev) (getminor(dev) % BD_MAXPART)
58
59 typedef struct bd bd_t;
60 typedef struct bd_xfer_impl bd_xfer_impl_t;
61
62 struct bd {
63 void *d_private;
64 dev_info_t *d_dip;
65 kmutex_t d_ocmutex;
66 kmutex_t d_iomutex;
67 kmutex_t *d_errmutex;
68 kmutex_t d_statemutex;
69 kcondvar_t d_statecv;
70 enum dkio_state d_state;
71 cmlb_handle_t d_cmlbh;
72 unsigned d_open_lyr[BD_MAXPART]; /* open count */
73 uint64_t d_open_excl; /* bit mask indexed by partition */
74 uint64_t d_open_reg[OTYPCNT]; /* bit mask */
75
76 uint32_t d_qsize;
77 uint32_t d_qactive;
78 uint32_t d_maxxfer;
79 uint32_t d_blkshift;
80 uint32_t d_pblkshift;
81 uint64_t d_numblks;
82 ddi_devid_t d_devid;
83
84 kmem_cache_t *d_cache;
85 list_t d_runq;
86 list_t d_waitq;
87 kstat_t *d_ksp;
88 kstat_io_t *d_kiop;
89 kstat_t *d_errstats;
90 struct bd_errstats *d_kerr;
91
92 boolean_t d_rdonly;
93 boolean_t d_ssd;
94 boolean_t d_removable;
95 boolean_t d_hotpluggable;
96 boolean_t d_use_dma;
97
98 ddi_dma_attr_t d_dma;
99 bd_ops_t d_ops;
100 bd_handle_t d_handle;
101 };
102
103 struct bd_handle {
104 bd_ops_t h_ops;
105 ddi_dma_attr_t *h_dma;
106 dev_info_t *h_parent;
107 dev_info_t *h_child;
108 void *h_private;
109 bd_t *h_bd;
110 char *h_name;
111 char h_addr[30]; /* enough for w%0.16x,%X */
112 };
113
114 struct bd_xfer_impl {
115 bd_xfer_t i_public;
116 list_node_t i_linkage;
117 bd_t *i_bd;
118 buf_t *i_bp;
119 uint_t i_num_win;
120 uint_t i_cur_win;
121 off_t i_offset;
122 int (*i_func)(void *, bd_xfer_t *);
123 uint32_t i_blkshift;
124 size_t i_len;
125 size_t i_resid;
126 };
127
128 #define i_dmah i_public.x_dmah
129 #define i_dmac i_public.x_dmac
130 #define i_ndmac i_public.x_ndmac
131 #define i_kaddr i_public.x_kaddr
132 #define i_nblks i_public.x_nblks
133 #define i_blkno i_public.x_blkno
134 #define i_flags i_public.x_flags
135
136
137 /*
138 * Private prototypes.
139 */
140
141 static void bd_prop_update_inqstring(dev_info_t *, char *, char *, size_t);
142 static void bd_create_inquiry_props(dev_info_t *, bd_drive_t *);
143 static void bd_create_errstats(bd_t *, int, bd_drive_t *);
144 static void bd_errstats_setstr(kstat_named_t *, char *, size_t, char *);
145 static void bd_init_errstats(bd_t *, bd_drive_t *);
146
147 static int bd_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
148 static int bd_attach(dev_info_t *, ddi_attach_cmd_t);
149 static int bd_detach(dev_info_t *, ddi_detach_cmd_t);
150
151 static int bd_open(dev_t *, int, int, cred_t *);
152 static int bd_close(dev_t, int, int, cred_t *);
153 static int bd_strategy(struct buf *);
154 static int bd_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
155 static int bd_dump(dev_t, caddr_t, daddr_t, int);
156 static int bd_read(dev_t, struct uio *, cred_t *);
157 static int bd_write(dev_t, struct uio *, cred_t *);
158 static int bd_aread(dev_t, struct aio_req *, cred_t *);
159 static int bd_awrite(dev_t, struct aio_req *, cred_t *);
160 static int bd_prop_op(dev_t, dev_info_t *, ddi_prop_op_t, int, char *,
161 caddr_t, int *);
162
163 static int bd_tg_rdwr(dev_info_t *, uchar_t, void *, diskaddr_t, size_t,
164 void *);
165 static int bd_tg_getinfo(dev_info_t *, int, void *, void *);
166 static int bd_xfer_ctor(void *, void *, int);
167 static void bd_xfer_dtor(void *, void *);
168 static void bd_sched(bd_t *);
169 static void bd_submit(bd_t *, bd_xfer_impl_t *);
170 static void bd_runq_exit(bd_xfer_impl_t *, int);
171 static void bd_update_state(bd_t *);
172 static int bd_check_state(bd_t *, enum dkio_state *);
173 static int bd_flush_write_cache(bd_t *, struct dk_callback *);
174
175 struct cmlb_tg_ops bd_tg_ops = {
176 TG_DK_OPS_VERSION_1,
177 bd_tg_rdwr,
178 bd_tg_getinfo,
179 };
180
181 static struct cb_ops bd_cb_ops = {
182 bd_open, /* open */
183 bd_close, /* close */
184 bd_strategy, /* strategy */
185 nodev, /* print */
186 bd_dump, /* dump */
187 bd_read, /* read */
188 bd_write, /* write */
189 bd_ioctl, /* ioctl */
190 nodev, /* devmap */
191 nodev, /* mmap */
192 nodev, /* segmap */
193 nochpoll, /* poll */
194 bd_prop_op, /* cb_prop_op */
195 0, /* streamtab */
196 D_64BIT | D_MP, /* Driver comaptibility flag */
197 CB_REV, /* cb_rev */
198 bd_aread, /* async read */
199 bd_awrite /* async write */
200 };
201
202 struct dev_ops bd_dev_ops = {
203 DEVO_REV, /* devo_rev, */
204 0, /* refcnt */
205 bd_getinfo, /* getinfo */
206 nulldev, /* identify */
207 nulldev, /* probe */
208 bd_attach, /* attach */
209 bd_detach, /* detach */
210 nodev, /* reset */
211 &bd_cb_ops, /* driver operations */
212 NULL, /* bus operations */
213 NULL, /* power */
214 ddi_quiesce_not_needed, /* quiesce */
215 };
216
217 static struct modldrv modldrv = {
218 &mod_driverops,
219 "Generic Block Device",
220 &bd_dev_ops,
221 };
222
223 static struct modlinkage modlinkage = {
224 MODREV_1, { &modldrv, NULL }
225 };
226
227 static void *bd_state;
228 static krwlock_t bd_lock;
229
230 int
231 _init(void)
232 {
233 int rv;
234
235 rv = ddi_soft_state_init(&bd_state, sizeof (struct bd), 2);
236 if (rv != DDI_SUCCESS) {
237 return (rv);
238 }
239 rw_init(&bd_lock, NULL, RW_DRIVER, NULL);
240 rv = mod_install(&modlinkage);
241 if (rv != DDI_SUCCESS) {
242 rw_destroy(&bd_lock);
243 ddi_soft_state_fini(&bd_state);
244 }
245 return (rv);
246 }
247
248 int
249 _fini(void)
250 {
251 int rv;
252
253 rv = mod_remove(&modlinkage);
254 if (rv == DDI_SUCCESS) {
255 rw_destroy(&bd_lock);
256 ddi_soft_state_fini(&bd_state);
257 }
258 return (rv);
259 }
260
261 int
262 _info(struct modinfo *modinfop)
263 {
264 return (mod_info(&modlinkage, modinfop));
265 }
266
267 static int
268 bd_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
269 {
270 bd_t *bd;
271 minor_t inst;
272
273 _NOTE(ARGUNUSED(dip));
274
275 inst = BDINST((dev_t)arg);
276
277 switch (cmd) {
278 case DDI_INFO_DEVT2DEVINFO:
279 bd = ddi_get_soft_state(bd_state, inst);
280 if (bd == NULL) {
281 return (DDI_FAILURE);
282 }
283 *resultp = (void *)bd->d_dip;
284 break;
285
286 case DDI_INFO_DEVT2INSTANCE:
287 *resultp = (void *)(intptr_t)inst;
288 break;
289
290 default:
291 return (DDI_FAILURE);
292 }
293 return (DDI_SUCCESS);
294 }
295
296 static void
297 bd_prop_update_inqstring(dev_info_t *dip, char *name, char *data, size_t len)
298 {
299 int ilen;
300 char *data_string;
301
302 ilen = scsi_ascii_inquiry_len(data, len);
303 ASSERT3U(ilen, <=, len);
304 if (ilen <= 0)
305 return;
306 /* ensure null termination */
307 data_string = kmem_zalloc(ilen + 1, KM_SLEEP);
308 bcopy(data, data_string, ilen);
309 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, name, data_string);
310 kmem_free(data_string, ilen + 1);
311 }
312
313 static void
314 bd_create_inquiry_props(dev_info_t *dip, bd_drive_t *drive)
315 {
316 if (drive->d_vendor_len > 0)
317 bd_prop_update_inqstring(dip, INQUIRY_VENDOR_ID,
318 drive->d_vendor, drive->d_vendor_len);
319
320 if (drive->d_product_len > 0)
321 bd_prop_update_inqstring(dip, INQUIRY_PRODUCT_ID,
322 drive->d_product, drive->d_product_len);
323
324 if (drive->d_serial_len > 0)
325 bd_prop_update_inqstring(dip, INQUIRY_SERIAL_NO,
326 drive->d_serial, drive->d_serial_len);
327
328 if (drive->d_revision_len > 0)
329 bd_prop_update_inqstring(dip, INQUIRY_REVISION_ID,
330 drive->d_revision, drive->d_revision_len);
331 }
332
333 static void
334 bd_create_errstats(bd_t *bd, int inst, bd_drive_t *drive)
335 {
336 char ks_module[KSTAT_STRLEN];
337 char ks_name[KSTAT_STRLEN];
338 int ndata = sizeof (struct bd_errstats) / sizeof (kstat_named_t);
339
340 if (bd->d_errstats != NULL)
341 return;
342
343 (void) snprintf(ks_module, sizeof (ks_module), "%serr",
344 ddi_driver_name(bd->d_dip));
345 (void) snprintf(ks_name, sizeof (ks_name), "%s%d,err",
346 ddi_driver_name(bd->d_dip), inst);
347
348 bd->d_errstats = kstat_create(ks_module, inst, ks_name, "device_error",
349 KSTAT_TYPE_NAMED, ndata, KSTAT_FLAG_PERSISTENT);
350
351 if (bd->d_errstats == NULL) {
352 /*
353 * Even if we cannot create the kstat, we create a
354 * scratch kstat. The reason for this is to ensure
355 * that we can update the kstat all of the time,
356 * without adding an extra branch instruction.
357 */
358 bd->d_kerr = kmem_zalloc(sizeof (struct bd_errstats),
359 KM_SLEEP);
360 bd->d_errmutex = kmem_zalloc(sizeof (kmutex_t), KM_SLEEP);
361 mutex_init(bd->d_errmutex, NULL, MUTEX_DRIVER, NULL);
362 } else {
363 if (bd->d_errstats->ks_lock == NULL) {
364 bd->d_errstats->ks_lock = kmem_zalloc(sizeof (kmutex_t),
365 KM_SLEEP);
366 mutex_init(bd->d_errstats->ks_lock, NULL, MUTEX_DRIVER,
367 NULL);
368 }
369
370 bd->d_errmutex = bd->d_errstats->ks_lock;
371 bd->d_kerr = (struct bd_errstats *)bd->d_errstats->ks_data;
372 }
373
374 kstat_named_init(&bd->d_kerr->bd_softerrs, "Soft Errors",
375 KSTAT_DATA_UINT32);
376 kstat_named_init(&bd->d_kerr->bd_harderrs, "Hard Errors",
377 KSTAT_DATA_UINT32);
378 kstat_named_init(&bd->d_kerr->bd_transerrs, "Transport Errors",
379 KSTAT_DATA_UINT32);
380
381 if (drive->d_model_len > 0) {
382 kstat_named_init(&bd->d_kerr->bd_model, "Model",
383 KSTAT_DATA_STRING);
384 } else {
385 kstat_named_init(&bd->d_kerr->bd_vid, "Vendor",
386 KSTAT_DATA_STRING);
387 kstat_named_init(&bd->d_kerr->bd_pid, "Product",
388 KSTAT_DATA_STRING);
389 }
390
391 kstat_named_init(&bd->d_kerr->bd_revision, "Revision",
392 KSTAT_DATA_STRING);
393 kstat_named_init(&bd->d_kerr->bd_serial, "Serial No",
394 KSTAT_DATA_STRING);
395 kstat_named_init(&bd->d_kerr->bd_capacity, "Size",
396 KSTAT_DATA_ULONGLONG);
397 kstat_named_init(&bd->d_kerr->bd_rq_media_err, "Media Error",
398 KSTAT_DATA_UINT32);
399 kstat_named_init(&bd->d_kerr->bd_rq_ntrdy_err, "Device Not Ready",
400 KSTAT_DATA_UINT32);
401 kstat_named_init(&bd->d_kerr->bd_rq_nodev_err, "No Device",
402 KSTAT_DATA_UINT32);
403 kstat_named_init(&bd->d_kerr->bd_rq_recov_err, "Recoverable",
404 KSTAT_DATA_UINT32);
405 kstat_named_init(&bd->d_kerr->bd_rq_illrq_err, "Illegal Request",
406 KSTAT_DATA_UINT32);
407 kstat_named_init(&bd->d_kerr->bd_rq_pfa_err,
408 "Predictive Failure Analysis", KSTAT_DATA_UINT32);
409
410 bd->d_errstats->ks_private = bd;
411
412 kstat_install(bd->d_errstats);
413 }
414
415 static void
416 bd_errstats_setstr(kstat_named_t *k, char *str, size_t len, char *alt)
417 {
418 char *tmp;
419
420 if (KSTAT_NAMED_STR_PTR(k) == NULL) {
421 if (len > 0) {
422 tmp = kmem_alloc(len + 1, KM_SLEEP);
423 (void) strlcpy(tmp, str, len + 1);
424 } else {
425 tmp = alt;
426 }
427
428 kstat_named_setstr(k, tmp);
429 }
430 }
431
432 static void
433 bd_init_errstats(bd_t *bd, bd_drive_t *drive)
434 {
435 struct bd_errstats *est = bd->d_kerr;
436
437 mutex_enter(bd->d_errmutex);
438
439 if (drive->d_model_len > 0 &&
440 KSTAT_NAMED_STR_PTR(&est->bd_model) == NULL) {
441 bd_errstats_setstr(&est->bd_model, drive->d_model,
442 drive->d_model_len, NULL);
443 } else {
444 bd_errstats_setstr(&est->bd_vid, drive->d_vendor,
445 drive->d_vendor_len, "Unknown ");
446 bd_errstats_setstr(&est->bd_pid, drive->d_product,
447 drive->d_product_len, "Unknown ");
448 }
449
450 bd_errstats_setstr(&est->bd_revision, drive->d_revision,
451 drive->d_revision_len, "0001");
452 bd_errstats_setstr(&est->bd_serial, drive->d_serial,
453 drive->d_serial_len, "0 ");
454
455 mutex_exit(bd->d_errmutex);
456 }
457
458 static int
459 bd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
460 {
461 int inst;
462 bd_handle_t hdl;
463 bd_t *bd;
464 bd_drive_t drive;
465 int rv;
466 char name[16];
467 char kcache[32];
468
469 switch (cmd) {
470 case DDI_ATTACH:
471 break;
472 case DDI_RESUME:
473 /* We don't do anything native for suspend/resume */
474 return (DDI_SUCCESS);
475 default:
476 return (DDI_FAILURE);
477 }
478
479 inst = ddi_get_instance(dip);
480 hdl = ddi_get_parent_data(dip);
481
482 (void) snprintf(name, sizeof (name), "%s%d",
483 ddi_driver_name(dip), ddi_get_instance(dip));
484 (void) snprintf(kcache, sizeof (kcache), "%s_xfer", name);
485
486 if (hdl == NULL) {
487 cmn_err(CE_WARN, "%s: missing parent data!", name);
488 return (DDI_FAILURE);
489 }
490
491 if (ddi_soft_state_zalloc(bd_state, inst) != DDI_SUCCESS) {
492 cmn_err(CE_WARN, "%s: unable to zalloc soft state!", name);
493 return (DDI_FAILURE);
494 }
495 bd = ddi_get_soft_state(bd_state, inst);
496
497 if (hdl->h_dma) {
498 bd->d_dma = *(hdl->h_dma);
499 bd->d_dma.dma_attr_granular =
500 max(DEV_BSIZE, bd->d_dma.dma_attr_granular);
501 bd->d_use_dma = B_TRUE;
502
503 if (bd->d_maxxfer &&
504 (bd->d_maxxfer != bd->d_dma.dma_attr_maxxfer)) {
505 cmn_err(CE_WARN,
506 "%s: inconsistent maximum transfer size!",
507 name);
508 /* We force it */
509 bd->d_maxxfer = bd->d_dma.dma_attr_maxxfer;
510 } else {
511 bd->d_maxxfer = bd->d_dma.dma_attr_maxxfer;
512 }
513 } else {
514 bd->d_use_dma = B_FALSE;
515 if (bd->d_maxxfer == 0) {
516 bd->d_maxxfer = 1024 * 1024;
517 }
518 }
519 bd->d_ops = hdl->h_ops;
520 bd->d_private = hdl->h_private;
521 bd->d_blkshift = 9; /* 512 bytes, to start */
522
523 if (bd->d_maxxfer % DEV_BSIZE) {
524 cmn_err(CE_WARN, "%s: maximum transfer misaligned!", name);
525 bd->d_maxxfer &= ~(DEV_BSIZE - 1);
526 }
527 if (bd->d_maxxfer < DEV_BSIZE) {
528 cmn_err(CE_WARN, "%s: maximum transfer size too small!", name);
529 ddi_soft_state_free(bd_state, inst);
530 return (DDI_FAILURE);
531 }
532
533 bd->d_dip = dip;
534 bd->d_handle = hdl;
535 hdl->h_bd = bd;
536 ddi_set_driver_private(dip, bd);
537
538 mutex_init(&bd->d_iomutex, NULL, MUTEX_DRIVER, NULL);
539 mutex_init(&bd->d_ocmutex, NULL, MUTEX_DRIVER, NULL);
540 mutex_init(&bd->d_statemutex, NULL, MUTEX_DRIVER, NULL);
541 cv_init(&bd->d_statecv, NULL, CV_DRIVER, NULL);
542
543 list_create(&bd->d_waitq, sizeof (bd_xfer_impl_t),
544 offsetof(struct bd_xfer_impl, i_linkage));
545 list_create(&bd->d_runq, sizeof (bd_xfer_impl_t),
546 offsetof(struct bd_xfer_impl, i_linkage));
547
548 bd->d_cache = kmem_cache_create(kcache, sizeof (bd_xfer_impl_t), 8,
549 bd_xfer_ctor, bd_xfer_dtor, NULL, bd, NULL, 0);
550
551 bd->d_ksp = kstat_create(ddi_driver_name(dip), inst, NULL, "disk",
552 KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT);
553 if (bd->d_ksp != NULL) {
554 bd->d_ksp->ks_lock = &bd->d_iomutex;
555 kstat_install(bd->d_ksp);
556 bd->d_kiop = bd->d_ksp->ks_data;
557 } else {
558 /*
559 * Even if we cannot create the kstat, we create a
560 * scratch kstat. The reason for this is to ensure
561 * that we can update the kstat all of the time,
562 * without adding an extra branch instruction.
563 */
564 bd->d_kiop = kmem_zalloc(sizeof (kstat_io_t), KM_SLEEP);
565 }
566
567 cmlb_alloc_handle(&bd->d_cmlbh);
568
569 bd->d_state = DKIO_NONE;
570
571 bzero(&drive, sizeof (drive));
572 bd->d_ops.o_drive_info(bd->d_private, &drive);
573 bd->d_qsize = drive.d_qsize;
574 bd->d_removable = drive.d_removable;
575 bd->d_hotpluggable = drive.d_hotpluggable;
576
577 if (drive.d_maxxfer && drive.d_maxxfer < bd->d_maxxfer)
578 bd->d_maxxfer = drive.d_maxxfer;
579
580 bd_create_inquiry_props(dip, &drive);
581
582 bd_create_errstats(bd, inst, &drive);
583 bd_init_errstats(bd, &drive);
584 bd_update_state(bd);
585
586 rv = cmlb_attach(dip, &bd_tg_ops, DTYPE_DIRECT,
587 bd->d_removable, bd->d_hotpluggable,
588 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
589 *(uint64_t *)drive.d_eui64 != 0 ? DDI_NT_BLOCK_BLKDEV :
590 drive.d_lun >= 0 ? DDI_NT_BLOCK_CHAN : DDI_NT_BLOCK,
591 CMLB_FAKE_LABEL_ONE_PARTITION, bd->d_cmlbh, 0);
592 if (rv != 0) {
593 cmlb_free_handle(&bd->d_cmlbh);
594 kmem_cache_destroy(bd->d_cache);
595 mutex_destroy(&bd->d_iomutex);
596 mutex_destroy(&bd->d_ocmutex);
597 mutex_destroy(&bd->d_statemutex);
598 cv_destroy(&bd->d_statecv);
599 list_destroy(&bd->d_waitq);
600 list_destroy(&bd->d_runq);
601 if (bd->d_ksp != NULL) {
602 kstat_delete(bd->d_ksp);
603 bd->d_ksp = NULL;
604 } else {
605 kmem_free(bd->d_kiop, sizeof (kstat_io_t));
606 }
607 ddi_soft_state_free(bd_state, inst);
608 return (DDI_FAILURE);
609 }
610
611 if (bd->d_ops.o_devid_init != NULL) {
612 rv = bd->d_ops.o_devid_init(bd->d_private, dip, &bd->d_devid);
613 if (rv == DDI_SUCCESS) {
614 if (ddi_devid_register(dip, bd->d_devid) !=
615 DDI_SUCCESS) {
616 cmn_err(CE_WARN,
617 "%s: unable to register devid", name);
618 }
619 }
620 }
621
622 /*
623 * Add a zero-length attribute to tell the world we support
624 * kernel ioctls (for layered drivers). Also set up properties
625 * used by HAL to identify removable media.
626 */
627 (void) ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
628 DDI_KERNEL_IOCTL, NULL, 0);
629 if (bd->d_removable) {
630 (void) ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
631 "removable-media", NULL, 0);
632 }
633 if (bd->d_hotpluggable) {
634 (void) ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
635 "hotpluggable", NULL, 0);
636 }
637
638 ddi_report_dev(dip);
639
640 return (DDI_SUCCESS);
641 }
642
643 static int
644 bd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
645 {
646 bd_t *bd;
647
648 bd = ddi_get_driver_private(dip);
649
650 switch (cmd) {
651 case DDI_DETACH:
652 break;
653 case DDI_SUSPEND:
654 /* We don't suspend, but our parent does */
655 return (DDI_SUCCESS);
656 default:
657 return (DDI_FAILURE);
658 }
659 if (bd->d_ksp != NULL) {
660 kstat_delete(bd->d_ksp);
661 bd->d_ksp = NULL;
662 } else {
663 kmem_free(bd->d_kiop, sizeof (kstat_io_t));
664 }
665
666 if (bd->d_errstats != NULL) {
667 kstat_delete(bd->d_errstats);
668 bd->d_errstats = NULL;
669 } else {
670 kmem_free(bd->d_kerr, sizeof (struct bd_errstats));
671 mutex_destroy(bd->d_errmutex);
672 }
673
674 cmlb_detach(bd->d_cmlbh, 0);
675 cmlb_free_handle(&bd->d_cmlbh);
676 if (bd->d_devid)
677 ddi_devid_free(bd->d_devid);
678 kmem_cache_destroy(bd->d_cache);
679 mutex_destroy(&bd->d_iomutex);
680 mutex_destroy(&bd->d_ocmutex);
681 mutex_destroy(&bd->d_statemutex);
682 cv_destroy(&bd->d_statecv);
683 list_destroy(&bd->d_waitq);
684 list_destroy(&bd->d_runq);
685 ddi_soft_state_free(bd_state, ddi_get_instance(dip));
686 return (DDI_SUCCESS);
687 }
688
689 static int
690 bd_xfer_ctor(void *buf, void *arg, int kmflag)
691 {
692 bd_xfer_impl_t *xi;
693 bd_t *bd = arg;
694 int (*dcb)(caddr_t);
695
696 if (kmflag == KM_PUSHPAGE || kmflag == KM_SLEEP) {
697 dcb = DDI_DMA_SLEEP;
698 } else {
699 dcb = DDI_DMA_DONTWAIT;
700 }
701
702 xi = buf;
703 bzero(xi, sizeof (*xi));
704 xi->i_bd = bd;
705
706 if (bd->d_use_dma) {
707 if (ddi_dma_alloc_handle(bd->d_dip, &bd->d_dma, dcb, NULL,
708 &xi->i_dmah) != DDI_SUCCESS) {
709 return (-1);
710 }
711 }
712
713 return (0);
714 }
715
716 static void
717 bd_xfer_dtor(void *buf, void *arg)
718 {
719 bd_xfer_impl_t *xi = buf;
720
721 _NOTE(ARGUNUSED(arg));
722
723 if (xi->i_dmah)
724 ddi_dma_free_handle(&xi->i_dmah);
725 xi->i_dmah = NULL;
726 }
727
728 static bd_xfer_impl_t *
729 bd_xfer_alloc(bd_t *bd, struct buf *bp, int (*func)(void *, bd_xfer_t *),
730 int kmflag)
731 {
732 bd_xfer_impl_t *xi;
733 int rv = 0;
734 int status;
735 unsigned dir;
736 int (*cb)(caddr_t);
737 size_t len;
738 uint32_t shift;
739
740 if (kmflag == KM_SLEEP) {
741 cb = DDI_DMA_SLEEP;
742 } else {
743 cb = DDI_DMA_DONTWAIT;
744 }
745
746 xi = kmem_cache_alloc(bd->d_cache, kmflag);
747 if (xi == NULL) {
748 bioerror(bp, ENOMEM);
749 return (NULL);
750 }
751
752 ASSERT(bp);
753
754 xi->i_bp = bp;
755 xi->i_func = func;
756 xi->i_blkno = bp->b_lblkno;
757
758 if (bp->b_bcount == 0) {
759 xi->i_len = 0;
760 xi->i_nblks = 0;
761 xi->i_kaddr = NULL;
762 xi->i_resid = 0;
763 xi->i_num_win = 0;
764 goto done;
765 }
766
767 if (bp->b_flags & B_READ) {
768 dir = DDI_DMA_READ;
769 xi->i_func = bd->d_ops.o_read;
770 } else {
771 dir = DDI_DMA_WRITE;
772 xi->i_func = bd->d_ops.o_write;
773 }
774
775 shift = bd->d_blkshift;
776 xi->i_blkshift = shift;
777
778 if (!bd->d_use_dma) {
779 bp_mapin(bp);
780 rv = 0;
781 xi->i_offset = 0;
782 xi->i_num_win =
783 (bp->b_bcount + (bd->d_maxxfer - 1)) / bd->d_maxxfer;
784 xi->i_cur_win = 0;
785 xi->i_len = min(bp->b_bcount, bd->d_maxxfer);
786 xi->i_nblks = xi->i_len >> shift;
787 xi->i_kaddr = bp->b_un.b_addr;
788 xi->i_resid = bp->b_bcount;
789 } else {
790
791 /*
792 * We have to use consistent DMA if the address is misaligned.
793 */
794 if (((bp->b_flags & (B_PAGEIO | B_REMAPPED)) != B_PAGEIO) &&
795 ((uintptr_t)bp->b_un.b_addr & 0x7)) {
796 dir |= DDI_DMA_CONSISTENT | DDI_DMA_PARTIAL;
797 } else {
798 dir |= DDI_DMA_STREAMING | DDI_DMA_PARTIAL;
799 }
800
801 status = ddi_dma_buf_bind_handle(xi->i_dmah, bp, dir, cb,
802 NULL, &xi->i_dmac, &xi->i_ndmac);
803 switch (status) {
804 case DDI_DMA_MAPPED:
805 xi->i_num_win = 1;
806 xi->i_cur_win = 0;
807 xi->i_offset = 0;
808 xi->i_len = bp->b_bcount;
809 xi->i_nblks = xi->i_len >> shift;
810 xi->i_resid = bp->b_bcount;
811 rv = 0;
812 break;
813 case DDI_DMA_PARTIAL_MAP:
814 xi->i_cur_win = 0;
815
816 if ((ddi_dma_numwin(xi->i_dmah, &xi->i_num_win) !=
817 DDI_SUCCESS) ||
818 (ddi_dma_getwin(xi->i_dmah, 0, &xi->i_offset,
819 &len, &xi->i_dmac, &xi->i_ndmac) !=
820 DDI_SUCCESS) ||
821 (P2PHASE(len, shift) != 0)) {
822 (void) ddi_dma_unbind_handle(xi->i_dmah);
823 rv = EFAULT;
824 goto done;
825 }
826 xi->i_len = len;
827 xi->i_nblks = xi->i_len >> shift;
828 xi->i_resid = bp->b_bcount;
829 rv = 0;
830 break;
831 case DDI_DMA_NORESOURCES:
832 rv = EAGAIN;
833 goto done;
834 case DDI_DMA_TOOBIG:
835 rv = EINVAL;
836 goto done;
837 case DDI_DMA_NOMAPPING:
838 case DDI_DMA_INUSE:
839 default:
840 rv = EFAULT;
841 goto done;
842 }
843 }
844
845 done:
846 if (rv != 0) {
847 kmem_cache_free(bd->d_cache, xi);
848 bioerror(bp, rv);
849 return (NULL);
850 }
851
852 return (xi);
853 }
854
855 static void
856 bd_xfer_free(bd_xfer_impl_t *xi)
857 {
858 if (xi->i_dmah) {
859 (void) ddi_dma_unbind_handle(xi->i_dmah);
860 }
861 kmem_cache_free(xi->i_bd->d_cache, xi);
862 }
863
864 static int
865 bd_open(dev_t *devp, int flag, int otyp, cred_t *credp)
866 {
867 dev_t dev = *devp;
868 bd_t *bd;
869 minor_t part;
870 minor_t inst;
871 uint64_t mask;
872 boolean_t ndelay;
873 int rv;
874 diskaddr_t nblks;
875 diskaddr_t lba;
876
877 _NOTE(ARGUNUSED(credp));
878
879 part = BDPART(dev);
880 inst = BDINST(dev);
881
882 if (otyp >= OTYPCNT)
883 return (EINVAL);
884
885 ndelay = (flag & (FNDELAY | FNONBLOCK)) ? B_TRUE : B_FALSE;
886
887 /*
888 * Block any DR events from changing the set of registered
889 * devices while we function.
890 */
891 rw_enter(&bd_lock, RW_READER);
892 if ((bd = ddi_get_soft_state(bd_state, inst)) == NULL) {
893 rw_exit(&bd_lock);
894 return (ENXIO);
895 }
896
897 mutex_enter(&bd->d_ocmutex);
898
899 ASSERT(part < 64);
900 mask = (1U << part);
901
902 bd_update_state(bd);
903
904 if (cmlb_validate(bd->d_cmlbh, 0, 0) != 0) {
905
906 /* non-blocking opens are allowed to succeed */
907 if (!ndelay) {
908 rv = ENXIO;
909 goto done;
910 }
911 } else if (cmlb_partinfo(bd->d_cmlbh, part, &nblks, &lba,
912 NULL, NULL, 0) == 0) {
913
914 /*
915 * We read the partinfo, verify valid ranges. If the
916 * partition is invalid, and we aren't blocking or
917 * doing a raw access, then fail. (Non-blocking and
918 * raw accesses can still succeed to allow a disk with
919 * bad partition data to opened by format and fdisk.)
920 */
921 if ((!nblks) && ((!ndelay) || (otyp != OTYP_CHR))) {
922 rv = ENXIO;
923 goto done;
924 }
925 } else if (!ndelay) {
926 /*
927 * cmlb_partinfo failed -- invalid partition or no
928 * disk label.
929 */
930 rv = ENXIO;
931 goto done;
932 }
933
934 if ((flag & FWRITE) && bd->d_rdonly) {
935 rv = EROFS;
936 goto done;
937 }
938
939 if ((bd->d_open_excl) & (mask)) {
940 rv = EBUSY;
941 goto done;
942 }
943 if (flag & FEXCL) {
944 if (bd->d_open_lyr[part]) {
945 rv = EBUSY;
946 goto done;
947 }
948 for (int i = 0; i < OTYP_LYR; i++) {
949 if (bd->d_open_reg[i] & mask) {
950 rv = EBUSY;
951 goto done;
952 }
953 }
954 }
955
956 if (otyp == OTYP_LYR) {
957 bd->d_open_lyr[part]++;
958 } else {
959 bd->d_open_reg[otyp] |= mask;
960 }
961 if (flag & FEXCL) {
962 bd->d_open_excl |= mask;
963 }
964
965 rv = 0;
966 done:
967 mutex_exit(&bd->d_ocmutex);
968 rw_exit(&bd_lock);
969
970 return (rv);
971 }
972
973 static int
974 bd_close(dev_t dev, int flag, int otyp, cred_t *credp)
975 {
976 bd_t *bd;
977 minor_t inst;
978 minor_t part;
979 uint64_t mask;
980 boolean_t last = B_TRUE;
981
982 _NOTE(ARGUNUSED(flag));
983 _NOTE(ARGUNUSED(credp));
984
985 part = BDPART(dev);
986 inst = BDINST(dev);
987
988 ASSERT(part < 64);
989 mask = (1U << part);
990
991 rw_enter(&bd_lock, RW_READER);
992
993 if ((bd = ddi_get_soft_state(bd_state, inst)) == NULL) {
994 rw_exit(&bd_lock);
995 return (ENXIO);
996 }
997
998 mutex_enter(&bd->d_ocmutex);
999 if (bd->d_open_excl & mask) {
1000 bd->d_open_excl &= ~mask;
1001 }
1002 if (otyp == OTYP_LYR) {
1003 bd->d_open_lyr[part]--;
1004 } else {
1005 bd->d_open_reg[otyp] &= ~mask;
1006 }
1007 for (int i = 0; i < 64; i++) {
1008 if (bd->d_open_lyr[part]) {
1009 last = B_FALSE;
1010 }
1011 }
1012 for (int i = 0; last && (i < OTYP_LYR); i++) {
1013 if (bd->d_open_reg[i]) {
1014 last = B_FALSE;
1015 }
1016 }
1017 mutex_exit(&bd->d_ocmutex);
1018
1019 if (last) {
1020 cmlb_invalidate(bd->d_cmlbh, 0);
1021 }
1022 rw_exit(&bd_lock);
1023
1024 return (0);
1025 }
1026
1027 static int
1028 bd_dump(dev_t dev, caddr_t caddr, daddr_t blkno, int nblk)
1029 {
1030 minor_t inst;
1031 minor_t part;
1032 diskaddr_t pstart;
1033 diskaddr_t psize;
1034 bd_t *bd;
1035 bd_xfer_impl_t *xi;
1036 buf_t *bp;
1037 int rv;
1038
1039 rw_enter(&bd_lock, RW_READER);
1040
1041 part = BDPART(dev);
1042 inst = BDINST(dev);
1043
1044 if ((bd = ddi_get_soft_state(bd_state, inst)) == NULL) {
1045 rw_exit(&bd_lock);
1046 return (ENXIO);
1047 }
1048 /*
1049 * do cmlb, but do it synchronously unless we already have the
1050 * partition (which we probably should.)
1051 */
1052 if (cmlb_partinfo(bd->d_cmlbh, part, &psize, &pstart, NULL, NULL,
1053 (void *)1)) {
1054 rw_exit(&bd_lock);
1055 return (ENXIO);
1056 }
1057
1058 if ((blkno + nblk) > psize) {
1059 rw_exit(&bd_lock);
1060 return (EINVAL);
1061 }
1062 bp = getrbuf(KM_NOSLEEP);
1063 if (bp == NULL) {
1064 rw_exit(&bd_lock);
1065 return (ENOMEM);
1066 }
1067
1068 bp->b_bcount = nblk << bd->d_blkshift;
1069 bp->b_resid = bp->b_bcount;
1070 bp->b_lblkno = blkno;
1071 bp->b_un.b_addr = caddr;
1072
1073 xi = bd_xfer_alloc(bd, bp, bd->d_ops.o_write, KM_NOSLEEP);
1074 if (xi == NULL) {
1075 rw_exit(&bd_lock);
1076 freerbuf(bp);
1077 return (ENOMEM);
1078 }
1079 xi->i_blkno = blkno + pstart;
1080 xi->i_flags = BD_XFER_POLL;
1081 bd_submit(bd, xi);
1082 rw_exit(&bd_lock);
1083
1084 /*
1085 * Generally, we should have run this entirely synchronously
1086 * at this point and the biowait call should be a no-op. If
1087 * it didn't happen this way, it's a bug in the underlying
1088 * driver not honoring BD_XFER_POLL.
1089 */
1090 (void) biowait(bp);
1091 rv = geterror(bp);
1092 freerbuf(bp);
1093 return (rv);
1094 }
1095
1096 void
1097 bd_minphys(struct buf *bp)
1098 {
1099 minor_t inst;
1100 bd_t *bd;
1101 inst = BDINST(bp->b_edev);
1102
1103 bd = ddi_get_soft_state(bd_state, inst);
1104
1105 /*
1106 * In a non-debug kernel, bd_strategy will catch !bd as
1107 * well, and will fail nicely.
1108 */
1109 ASSERT(bd);
1110
1111 if (bp->b_bcount > bd->d_maxxfer)
1112 bp->b_bcount = bd->d_maxxfer;
1113 }
1114
1115 static int
1116 bd_read(dev_t dev, struct uio *uio, cred_t *credp)
1117 {
1118 _NOTE(ARGUNUSED(credp));
1119 return (physio(bd_strategy, NULL, dev, B_READ, bd_minphys, uio));
1120 }
1121
1122 static int
1123 bd_write(dev_t dev, struct uio *uio, cred_t *credp)
1124 {
1125 _NOTE(ARGUNUSED(credp));
1126 return (physio(bd_strategy, NULL, dev, B_WRITE, bd_minphys, uio));
1127 }
1128
1129 static int
1130 bd_aread(dev_t dev, struct aio_req *aio, cred_t *credp)
1131 {
1132 _NOTE(ARGUNUSED(credp));
1133 return (aphysio(bd_strategy, anocancel, dev, B_READ, bd_minphys, aio));
1134 }
1135
1136 static int
1137 bd_awrite(dev_t dev, struct aio_req *aio, cred_t *credp)
1138 {
1139 _NOTE(ARGUNUSED(credp));
1140 return (aphysio(bd_strategy, anocancel, dev, B_WRITE, bd_minphys, aio));
1141 }
1142
1143 static int
1144 bd_strategy(struct buf *bp)
1145 {
1146 minor_t inst;
1147 minor_t part;
1148 bd_t *bd;
1149 diskaddr_t p_lba;
1150 diskaddr_t p_nblks;
1151 diskaddr_t b_nblks;
1152 bd_xfer_impl_t *xi;
1153 uint32_t shift;
1154 int (*func)(void *, bd_xfer_t *);
1155
1156 part = BDPART(bp->b_edev);
1157 inst = BDINST(bp->b_edev);
1158
1159 ASSERT(bp);
1160
1161 bp->b_resid = bp->b_bcount;
1162
1163 if ((bd = ddi_get_soft_state(bd_state, inst)) == NULL) {
1164 bioerror(bp, ENXIO);
1165 biodone(bp);
1166 return (0);
1167 }
1168
1169 if (cmlb_partinfo(bd->d_cmlbh, part, &p_nblks, &p_lba,
1170 NULL, NULL, 0)) {
1171 bioerror(bp, ENXIO);
1172 biodone(bp);
1173 return (0);
1174 }
1175
1176 shift = bd->d_blkshift;
1177
1178 if ((P2PHASE(bp->b_bcount, (1U << shift)) != 0) ||
1179 (bp->b_lblkno > p_nblks)) {
1180 bioerror(bp, ENXIO);
1181 biodone(bp);
1182 return (0);
1183 }
1184 b_nblks = bp->b_bcount >> shift;
1185 if ((bp->b_lblkno == p_nblks) || (bp->b_bcount == 0)) {
1186 biodone(bp);
1187 return (0);
1188 }
1189
1190 if ((b_nblks + bp->b_lblkno) > p_nblks) {
1191 bp->b_resid = ((bp->b_lblkno + b_nblks - p_nblks) << shift);
1192 bp->b_bcount -= bp->b_resid;
1193 } else {
1194 bp->b_resid = 0;
1195 }
1196 func = (bp->b_flags & B_READ) ? bd->d_ops.o_read : bd->d_ops.o_write;
1197
1198 xi = bd_xfer_alloc(bd, bp, func, KM_NOSLEEP);
1199 if (xi == NULL) {
1200 xi = bd_xfer_alloc(bd, bp, func, KM_PUSHPAGE);
1201 }
1202 if (xi == NULL) {
1203 /* bd_request_alloc will have done bioerror */
1204 biodone(bp);
1205 return (0);
1206 }
1207 xi->i_blkno = bp->b_lblkno + p_lba;
1208
1209 bd_submit(bd, xi);
1210
1211 return (0);
1212 }
1213
1214 static int
1215 bd_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp, int *rvalp)
1216 {
1217 minor_t inst;
1218 uint16_t part;
1219 bd_t *bd;
1220 void *ptr = (void *)arg;
1221 int rv;
1222
1223 part = BDPART(dev);
1224 inst = BDINST(dev);
1225
1226 if ((bd = ddi_get_soft_state(bd_state, inst)) == NULL) {
1227 return (ENXIO);
1228 }
1229
1230 rv = cmlb_ioctl(bd->d_cmlbh, dev, cmd, arg, flag, credp, rvalp, 0);
1231 if (rv != ENOTTY)
1232 return (rv);
1233
1234 if (rvalp != NULL) {
1235 /* the return value of the ioctl is 0 by default */
1236 *rvalp = 0;
1237 }
1238
1239 switch (cmd) {
1240 case DKIOCGMEDIAINFO: {
1241 struct dk_minfo minfo;
1242
1243 /* make sure our state information is current */
1244 bd_update_state(bd);
1245 bzero(&minfo, sizeof (minfo));
1246 minfo.dki_media_type = DK_FIXED_DISK;
1247 minfo.dki_lbsize = (1U << bd->d_blkshift);
1248 minfo.dki_capacity = bd->d_numblks;
1249 if (ddi_copyout(&minfo, ptr, sizeof (minfo), flag)) {
1250 return (EFAULT);
1251 }
1252 return (0);
1253 }
1254 case DKIOCGMEDIAINFOEXT: {
1255 struct dk_minfo_ext miext;
1256
1257 /* make sure our state information is current */
1258 bd_update_state(bd);
1259 bzero(&miext, sizeof (miext));
1260 miext.dki_media_type = DK_FIXED_DISK;
1261 miext.dki_lbsize = (1U << bd->d_blkshift);
1262 miext.dki_pbsize = (1U << bd->d_pblkshift);
1263 miext.dki_capacity = bd->d_numblks;
1264 if (ddi_copyout(&miext, ptr, sizeof (miext), flag)) {
1265 return (EFAULT);
1266 }
1267 return (0);
1268 }
1269 case DKIOCINFO: {
1270 struct dk_cinfo cinfo;
1271 bzero(&cinfo, sizeof (cinfo));
1272 cinfo.dki_ctype = DKC_BLKDEV;
1273 cinfo.dki_cnum = ddi_get_instance(ddi_get_parent(bd->d_dip));
1274 (void) snprintf(cinfo.dki_cname, sizeof (cinfo.dki_cname),
1275 "%s", ddi_driver_name(ddi_get_parent(bd->d_dip)));
1276 (void) snprintf(cinfo.dki_dname, sizeof (cinfo.dki_dname),
1277 "%s", ddi_driver_name(bd->d_dip));
1278 cinfo.dki_unit = inst;
1279 cinfo.dki_flags = DKI_FMTVOL;
1280 cinfo.dki_partition = part;
1281 cinfo.dki_maxtransfer = bd->d_maxxfer / DEV_BSIZE;
1282 cinfo.dki_addr = 0;
1283 cinfo.dki_slave = 0;
1284 cinfo.dki_space = 0;
1285 cinfo.dki_prio = 0;
1286 cinfo.dki_vec = 0;
1287 if (ddi_copyout(&cinfo, ptr, sizeof (cinfo), flag)) {
1288 return (EFAULT);
1289 }
1290 return (0);
1291 }
1292 case DKIOCREMOVABLE: {
1293 int i;
1294 i = bd->d_removable ? 1 : 0;
1295 if (ddi_copyout(&i, ptr, sizeof (i), flag)) {
1296 return (EFAULT);
1297 }
1298 return (0);
1299 }
1300 case DKIOCHOTPLUGGABLE: {
1301 int i;
1302 i = bd->d_hotpluggable ? 1 : 0;
1303 if (ddi_copyout(&i, ptr, sizeof (i), flag)) {
1304 return (EFAULT);
1305 }
1306 return (0);
1307 }
1308 case DKIOCREADONLY: {
1309 int i;
1310 i = bd->d_rdonly ? 1 : 0;
1311 if (ddi_copyout(&i, ptr, sizeof (i), flag)) {
1312 return (EFAULT);
1313 }
1314 return (0);
1315 }
1316 case DKIOCSOLIDSTATE: {
1317 int i;
1318 i = bd->d_ssd ? 1 : 0;
1319 if (ddi_copyout(&i, ptr, sizeof (i), flag)) {
1320 return (EFAULT);
1321 }
1322 return (0);
1323 }
1324 case DKIOCSTATE: {
1325 enum dkio_state state;
1326 if (ddi_copyin(ptr, &state, sizeof (state), flag)) {
1327 return (EFAULT);
1328 }
1329 if ((rv = bd_check_state(bd, &state)) != 0) {
1330 return (rv);
1331 }
1332 if (ddi_copyout(&state, ptr, sizeof (state), flag)) {
1333 return (EFAULT);
1334 }
1335 return (0);
1336 }
1337 case DKIOCFLUSHWRITECACHE: {
1338 struct dk_callback *dkc = NULL;
1339
1340 if (flag & FKIOCTL)
1341 dkc = (void *)arg;
1342
1343 rv = bd_flush_write_cache(bd, dkc);
1344 return (rv);
1345 }
1346
1347 default:
1348 break;
1349
1350 }
1351 return (ENOTTY);
1352 }
1353
1354 static int
1355 bd_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
1356 char *name, caddr_t valuep, int *lengthp)
1357 {
1358 bd_t *bd;
1359
1360 bd = ddi_get_soft_state(bd_state, ddi_get_instance(dip));
1361 if (bd == NULL)
1362 return (ddi_prop_op(dev, dip, prop_op, mod_flags,
1363 name, valuep, lengthp));
1364
1365 return (cmlb_prop_op(bd->d_cmlbh, dev, dip, prop_op, mod_flags, name,
1366 valuep, lengthp, BDPART(dev), 0));
1367 }
1368
1369
1370 static int
1371 bd_tg_rdwr(dev_info_t *dip, uchar_t cmd, void *bufaddr, diskaddr_t start,
1372 size_t length, void *tg_cookie)
1373 {
1374 bd_t *bd;
1375 buf_t *bp;
1376 bd_xfer_impl_t *xi;
1377 int rv;
1378 int (*func)(void *, bd_xfer_t *);
1379 int kmflag;
1380
1381 /*
1382 * If we are running in polled mode (such as during dump(9e)
1383 * execution), then we cannot sleep for kernel allocations.
1384 */
1385 kmflag = tg_cookie ? KM_NOSLEEP : KM_SLEEP;
1386
1387 bd = ddi_get_soft_state(bd_state, ddi_get_instance(dip));
1388
1389 if (P2PHASE(length, (1U << bd->d_blkshift)) != 0) {
1390 /* We can only transfer whole blocks at a time! */
1391 return (EINVAL);
1392 }
1393
1394 if ((bp = getrbuf(kmflag)) == NULL) {
1395 return (ENOMEM);
1396 }
1397
1398 switch (cmd) {
1399 case TG_READ:
1400 bp->b_flags = B_READ;
1401 func = bd->d_ops.o_read;
1402 break;
1403 case TG_WRITE:
1404 bp->b_flags = B_WRITE;
1405 func = bd->d_ops.o_write;
1406 break;
1407 default:
1408 freerbuf(bp);
1409 return (EINVAL);
1410 }
1411
1412 bp->b_un.b_addr = bufaddr;
1413 bp->b_bcount = length;
1414 xi = bd_xfer_alloc(bd, bp, func, kmflag);
1415 if (xi == NULL) {
1416 rv = geterror(bp);
1417 freerbuf(bp);
1418 return (rv);
1419 }
1420 xi->i_flags = tg_cookie ? BD_XFER_POLL : 0;
1421 xi->i_blkno = start;
1422 bd_submit(bd, xi);
1423 (void) biowait(bp);
1424 rv = geterror(bp);
1425 freerbuf(bp);
1426
1427 return (rv);
1428 }
1429
1430 static int
1431 bd_tg_getinfo(dev_info_t *dip, int cmd, void *arg, void *tg_cookie)
1432 {
1433 bd_t *bd;
1434
1435 _NOTE(ARGUNUSED(tg_cookie));
1436 bd = ddi_get_soft_state(bd_state, ddi_get_instance(dip));
1437
1438 switch (cmd) {
1439 case TG_GETPHYGEOM:
1440 case TG_GETVIRTGEOM:
1441 /*
1442 * We don't have any "geometry" as such, let cmlb
1443 * fabricate something.
1444 */
1445 return (ENOTTY);
1446
1447 case TG_GETCAPACITY:
1448 bd_update_state(bd);
1449 *(diskaddr_t *)arg = bd->d_numblks;
1450 return (0);
1451
1452 case TG_GETBLOCKSIZE:
1453 *(uint32_t *)arg = (1U << bd->d_blkshift);
1454 return (0);
1455
1456 case TG_GETATTR:
1457 /*
1458 * It turns out that cmlb really doesn't do much for
1459 * non-writable media, but lets make the information
1460 * available for it in case it does more in the
1461 * future. (The value is currently used for
1462 * triggering special behavior for CD-ROMs.)
1463 */
1464 bd_update_state(bd);
1465 ((tg_attribute_t *)arg)->media_is_writable =
1466 bd->d_rdonly ? B_FALSE : B_TRUE;
1467 ((tg_attribute_t *)arg)->media_is_solid_state = bd->d_ssd;
1468 return (0);
1469
1470 default:
1471 return (EINVAL);
1472 }
1473 }
1474
1475
1476 static void
1477 bd_sched(bd_t *bd)
1478 {
1479 bd_xfer_impl_t *xi;
1480 struct buf *bp;
1481 int rv;
1482
1483 mutex_enter(&bd->d_iomutex);
1484
1485 while ((bd->d_qactive < bd->d_qsize) &&
1486 ((xi = list_remove_head(&bd->d_waitq)) != NULL)) {
1487 bd->d_qactive++;
1488 kstat_waitq_to_runq(bd->d_kiop);
1489 list_insert_tail(&bd->d_runq, xi);
1490
1491 /*
1492 * Submit the job to the driver. We drop the I/O mutex
1493 * so that we can deal with the case where the driver
1494 * completion routine calls back into us synchronously.
1495 */
1496
1497 mutex_exit(&bd->d_iomutex);
1498
1499 rv = xi->i_func(bd->d_private, &xi->i_public);
1500 if (rv != 0) {
1501 bp = xi->i_bp;
1502 bioerror(bp, rv);
1503 biodone(bp);
1504
1505 atomic_inc_32(&bd->d_kerr->bd_transerrs.value.ui32);
1506
1507 mutex_enter(&bd->d_iomutex);
1508 bd->d_qactive--;
1509 kstat_runq_exit(bd->d_kiop);
1510 list_remove(&bd->d_runq, xi);
1511 bd_xfer_free(xi);
1512 } else {
1513 mutex_enter(&bd->d_iomutex);
1514 }
1515 }
1516
1517 mutex_exit(&bd->d_iomutex);
1518 }
1519
1520 static void
1521 bd_submit(bd_t *bd, bd_xfer_impl_t *xi)
1522 {
1523 mutex_enter(&bd->d_iomutex);
1524 list_insert_tail(&bd->d_waitq, xi);
1525 kstat_waitq_enter(bd->d_kiop);
1526 mutex_exit(&bd->d_iomutex);
1527
1528 bd_sched(bd);
1529 }
1530
1531 static void
1532 bd_runq_exit(bd_xfer_impl_t *xi, int err)
1533 {
1534 bd_t *bd = xi->i_bd;
1535 buf_t *bp = xi->i_bp;
1536
1537 mutex_enter(&bd->d_iomutex);
1538 bd->d_qactive--;
1539 kstat_runq_exit(bd->d_kiop);
1540 list_remove(&bd->d_runq, xi);
1541 mutex_exit(&bd->d_iomutex);
1542
1543 if (err == 0) {
1544 if (bp->b_flags & B_READ) {
1545 bd->d_kiop->reads++;
1546 bd->d_kiop->nread += (bp->b_bcount - xi->i_resid);
1547 } else {
1548 bd->d_kiop->writes++;
1549 bd->d_kiop->nwritten += (bp->b_bcount - xi->i_resid);
1550 }
1551 }
1552 bd_sched(bd);
1553 }
1554
1555 static void
1556 bd_update_state(bd_t *bd)
1557 {
1558 enum dkio_state state = DKIO_INSERTED;
1559 boolean_t docmlb = B_FALSE;
1560 bd_media_t media;
1561
1562 bzero(&media, sizeof (media));
1563
1564 mutex_enter(&bd->d_statemutex);
1565 if (bd->d_ops.o_media_info(bd->d_private, &media) != 0) {
1566 bd->d_numblks = 0;
1567 state = DKIO_EJECTED;
1568 goto done;
1569 }
1570
1571 if ((media.m_blksize < 512) ||
1572 (!ISP2(media.m_blksize)) ||
1573 (P2PHASE(bd->d_maxxfer, media.m_blksize))) {
1574 cmn_err(CE_WARN, "%s%d: Invalid media block size (%d)",
1575 ddi_driver_name(bd->d_dip), ddi_get_instance(bd->d_dip),
1576 media.m_blksize);
1577 /*
1578 * We can't use the media, treat it as not present.
1579 */
1580 state = DKIO_EJECTED;
1581 bd->d_numblks = 0;
1582 goto done;
1583 }
1584
1585 if (((1U << bd->d_blkshift) != media.m_blksize) ||
1586 (bd->d_numblks != media.m_nblks)) {
1587 /* Device size changed */
1588 docmlb = B_TRUE;
1589 }
1590
1591 bd->d_blkshift = ddi_ffs(media.m_blksize) - 1;
1592 bd->d_pblkshift = bd->d_blkshift;
1593 bd->d_numblks = media.m_nblks;
1594 bd->d_rdonly = media.m_readonly;
1595 bd->d_ssd = media.m_solidstate;
1596
1597 /*
1598 * Only use the supplied physical block size if it is non-zero,
1599 * greater or equal to the block size, and a power of 2. Ignore it
1600 * if not, it's just informational and we can still use the media.
1601 */
1602 if ((media.m_pblksize != 0) &&
1603 (media.m_pblksize >= media.m_blksize) &&
1604 (ISP2(media.m_pblksize)))
1605 bd->d_pblkshift = ddi_ffs(media.m_pblksize) - 1;
1606
1607 done:
1608 if (state != bd->d_state) {
1609 bd->d_state = state;
1610 cv_broadcast(&bd->d_statecv);
1611 docmlb = B_TRUE;
1612 }
1613 mutex_exit(&bd->d_statemutex);
1614
1615 bd->d_kerr->bd_capacity.value.ui64 = bd->d_numblks << bd->d_blkshift;
1616
1617 if (docmlb) {
1618 if (state == DKIO_INSERTED) {
1619 (void) cmlb_validate(bd->d_cmlbh, 0, 0);
1620 } else {
1621 cmlb_invalidate(bd->d_cmlbh, 0);
1622 }
1623 }
1624 }
1625
1626 static int
1627 bd_check_state(bd_t *bd, enum dkio_state *state)
1628 {
1629 clock_t when;
1630
1631 for (;;) {
1632
1633 bd_update_state(bd);
1634
1635 mutex_enter(&bd->d_statemutex);
1636
1637 if (bd->d_state != *state) {
1638 *state = bd->d_state;
1639 mutex_exit(&bd->d_statemutex);
1640 break;
1641 }
1642
1643 when = drv_usectohz(1000000);
1644 if (cv_reltimedwait_sig(&bd->d_statecv, &bd->d_statemutex,
1645 when, TR_CLOCK_TICK) == 0) {
1646 mutex_exit(&bd->d_statemutex);
1647 return (EINTR);
1648 }
1649
1650 mutex_exit(&bd->d_statemutex);
1651 }
1652
1653 return (0);
1654 }
1655
1656 static int
1657 bd_flush_write_cache_done(struct buf *bp)
1658 {
1659 struct dk_callback *dc = (void *)bp->b_private;
1660
1661 (*dc->dkc_callback)(dc->dkc_cookie, geterror(bp));
1662 kmem_free(dc, sizeof (*dc));
1663 freerbuf(bp);
1664 return (0);
1665 }
1666
1667 static int
1668 bd_flush_write_cache(bd_t *bd, struct dk_callback *dkc)
1669 {
1670 buf_t *bp;
1671 struct dk_callback *dc;
1672 bd_xfer_impl_t *xi;
1673 int rv;
1674
1675 if (bd->d_ops.o_sync_cache == NULL) {
1676 return (ENOTSUP);
1677 }
1678 if ((bp = getrbuf(KM_SLEEP)) == NULL) {
1679 return (ENOMEM);
1680 }
1681 bp->b_resid = 0;
1682 bp->b_bcount = 0;
1683
1684 xi = bd_xfer_alloc(bd, bp, bd->d_ops.o_sync_cache, KM_SLEEP);
1685 if (xi == NULL) {
1686 rv = geterror(bp);
1687 freerbuf(bp);
1688 return (rv);
1689 }
1690
1691 /* Make an asynchronous flush, but only if there is a callback */
1692 if (dkc != NULL && dkc->dkc_callback != NULL) {
1693 /* Make a private copy of the callback structure */
1694 dc = kmem_alloc(sizeof (*dc), KM_SLEEP);
1695 *dc = *dkc;
1696 bp->b_private = dc;
1697 bp->b_iodone = bd_flush_write_cache_done;
1698
1699 bd_submit(bd, xi);
1700 return (0);
1701 }
1702
1703 /* In case there is no callback, perform a synchronous flush */
1704 bd_submit(bd, xi);
1705 (void) biowait(bp);
1706 rv = geterror(bp);
1707 freerbuf(bp);
1708
1709 return (rv);
1710 }
1711
1712 /*
1713 * Nexus support.
1714 */
1715 int
1716 bd_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
1717 void *arg, void *result)
1718 {
1719 bd_handle_t hdl;
1720
1721 switch (ctlop) {
1722 case DDI_CTLOPS_REPORTDEV:
1723 cmn_err(CE_CONT, "?Block device: %s@%s, %s%d\n",
1724 ddi_node_name(rdip), ddi_get_name_addr(rdip),
1725 ddi_driver_name(rdip), ddi_get_instance(rdip));
1726 return (DDI_SUCCESS);
1727
1728 case DDI_CTLOPS_INITCHILD:
1729 hdl = ddi_get_parent_data((dev_info_t *)arg);
1730 if (hdl == NULL) {
1731 return (DDI_NOT_WELL_FORMED);
1732 }
1733 ddi_set_name_addr((dev_info_t *)arg, hdl->h_addr);
1734 return (DDI_SUCCESS);
1735
1736 case DDI_CTLOPS_UNINITCHILD:
1737 ddi_set_name_addr((dev_info_t *)arg, NULL);
1738 ndi_prop_remove_all((dev_info_t *)arg);
1739 return (DDI_SUCCESS);
1740
1741 default:
1742 return (ddi_ctlops(dip, rdip, ctlop, arg, result));
1743 }
1744 }
1745
1746 /*
1747 * Functions for device drivers.
1748 */
1749 bd_handle_t
1750 bd_alloc_handle(void *private, bd_ops_t *ops, ddi_dma_attr_t *dma, int kmflag)
1751 {
1752 bd_handle_t hdl;
1753
1754 hdl = kmem_zalloc(sizeof (*hdl), kmflag);
1755 if (hdl != NULL) {
1756 hdl->h_ops = *ops;
1757 hdl->h_dma = dma;
1758 hdl->h_private = private;
1759 }
1760
1761 return (hdl);
1762 }
1763
1764 void
1765 bd_free_handle(bd_handle_t hdl)
1766 {
1767 kmem_free(hdl, sizeof (*hdl));
1768 }
1769
1770 int
1771 bd_attach_handle(dev_info_t *dip, bd_handle_t hdl)
1772 {
1773 dev_info_t *child;
1774 bd_drive_t drive = { 0 };
1775
1776 /* if drivers don't override this, make it assume none */
1777 drive.d_lun = -1;
1778 hdl->h_ops.o_drive_info(hdl->h_private, &drive);
1779
1780 hdl->h_parent = dip;
1781 hdl->h_name = "blkdev";
1782
1783 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
1784 if (*(uint64_t *)drive.d_eui64 != 0) {
1785 if (drive.d_lun >= 0) {
1786 (void) snprintf(hdl->h_addr, sizeof (hdl->h_addr),
1787 "w%02X%02X%02X%02X%02X%02X%02X%02X,%X",
1788 drive.d_eui64[0], drive.d_eui64[1],
1789 drive.d_eui64[2], drive.d_eui64[3],
1790 drive.d_eui64[4], drive.d_eui64[5],
1791 drive.d_eui64[6], drive.d_eui64[7], drive.d_lun);
1792 } else {
1793 (void) snprintf(hdl->h_addr, sizeof (hdl->h_addr),
1794 "w%02X%02X%02X%02X%02X%02X%02X%02X",
1795 drive.d_eui64[0], drive.d_eui64[1],
1796 drive.d_eui64[2], drive.d_eui64[3],
1797 drive.d_eui64[4], drive.d_eui64[5],
1798 drive.d_eui64[6], drive.d_eui64[7]);
1799 }
1800 } else {
1801 if (drive.d_lun >= 0) {
1802 (void) snprintf(hdl->h_addr, sizeof (hdl->h_addr),
1803 "%X,%X", drive.d_target, drive.d_lun);
1804 } else {
1805 (void) snprintf(hdl->h_addr, sizeof (hdl->h_addr),
1806 "%X", drive.d_target);
1807 }
1808 }
1809
1810 if (ndi_devi_alloc(dip, hdl->h_name, (pnode_t)DEVI_SID_NODEID,
1811 &child) != NDI_SUCCESS) {
1812 cmn_err(CE_WARN, "%s%d: unable to allocate node %s@%s",
1813 ddi_driver_name(dip), ddi_get_instance(dip),
1814 "blkdev", hdl->h_addr);
1815 return (DDI_FAILURE);
1816 }
1817
1818 ddi_set_parent_data(child, hdl);
1819 hdl->h_child = child;
1820
1821 if (ndi_devi_online(child, 0) == NDI_FAILURE) {
1822 cmn_err(CE_WARN, "%s%d: failed bringing node %s@%s online",
1823 ddi_driver_name(dip), ddi_get_instance(dip),
1824 hdl->h_name, hdl->h_addr);
1825 (void) ndi_devi_free(child);
1826 return (DDI_FAILURE);
1827 }
1828
1829 return (DDI_SUCCESS);
1830 }
1831
1832 int
1833 bd_detach_handle(bd_handle_t hdl)
1834 {
1835 int circ;
1836 int rv;
1837 char *devnm;
1838
1839 if (hdl->h_child == NULL) {
1840 return (DDI_SUCCESS);
1841 }
1842 ndi_devi_enter(hdl->h_parent, &circ);
1843 if (i_ddi_node_state(hdl->h_child) < DS_INITIALIZED) {
1844 rv = ddi_remove_child(hdl->h_child, 0);
1845 } else {
1846 devnm = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
1847 (void) ddi_deviname(hdl->h_child, devnm);
1848 (void) devfs_clean(hdl->h_parent, devnm + 1, DV_CLEAN_FORCE);
1849 rv = ndi_devi_unconfig_one(hdl->h_parent, devnm + 1, NULL,
1850 NDI_DEVI_REMOVE | NDI_UNCONFIG);
1851 kmem_free(devnm, MAXNAMELEN + 1);
1852 }
1853 if (rv == 0) {
1854 hdl->h_child = NULL;
1855 }
1856
1857 ndi_devi_exit(hdl->h_parent, circ);
1858 return (rv == NDI_SUCCESS ? DDI_SUCCESS : DDI_FAILURE);
1859 }
1860
1861 void
1862 bd_xfer_done(bd_xfer_t *xfer, int err)
1863 {
1864 bd_xfer_impl_t *xi = (void *)xfer;
1865 buf_t *bp = xi->i_bp;
1866 int rv = DDI_SUCCESS;
1867 bd_t *bd = xi->i_bd;
1868 size_t len;
1869
1870 if (err != 0) {
1871 bd_runq_exit(xi, err);
1872 atomic_inc_32(&bd->d_kerr->bd_harderrs.value.ui32);
1873
1874 bp->b_resid += xi->i_resid;
1875 bd_xfer_free(xi);
1876 bioerror(bp, err);
1877 biodone(bp);
1878 return;
1879 }
1880
1881 xi->i_cur_win++;
1882 xi->i_resid -= xi->i_len;
1883
1884 if (xi->i_resid == 0) {
1885 /* Job completed succcessfully! */
1886 bd_runq_exit(xi, 0);
1887
1888 bd_xfer_free(xi);
1889 biodone(bp);
1890 return;
1891 }
1892
1893 xi->i_blkno += xi->i_nblks;
1894
1895 if (bd->d_use_dma) {
1896 /* More transfer still pending... advance to next DMA window. */
1897 rv = ddi_dma_getwin(xi->i_dmah, xi->i_cur_win,
1898 &xi->i_offset, &len, &xi->i_dmac, &xi->i_ndmac);
1899 } else {
1900 /* Advance memory window. */
1901 xi->i_kaddr += xi->i_len;
1902 xi->i_offset += xi->i_len;
1903 len = min(bp->b_bcount - xi->i_offset, bd->d_maxxfer);
1904 }
1905
1906
1907 if ((rv != DDI_SUCCESS) ||
1908 (P2PHASE(len, (1U << xi->i_blkshift) != 0))) {
1909 bd_runq_exit(xi, EFAULT);
1910
1911 bp->b_resid += xi->i_resid;
1912 bd_xfer_free(xi);
1913 bioerror(bp, EFAULT);
1914 biodone(bp);
1915 return;
1916 }
1917 xi->i_len = len;
1918 xi->i_nblks = len >> xi->i_blkshift;
1919
1920 /* Submit next window to hardware. */
1921 rv = xi->i_func(bd->d_private, &xi->i_public);
1922 if (rv != 0) {
1923 bd_runq_exit(xi, rv);
1924
1925 atomic_inc_32(&bd->d_kerr->bd_transerrs.value.ui32);
1926
1927 bp->b_resid += xi->i_resid;
1928 bd_xfer_free(xi);
1929 bioerror(bp, rv);
1930 biodone(bp);
1931 }
1932 }
1933
1934 void
1935 bd_error(bd_xfer_t *xfer, int error)
1936 {
1937 bd_xfer_impl_t *xi = (void *)xfer;
1938 bd_t *bd = xi->i_bd;
1939
1940 switch (error) {
1941 case BD_ERR_MEDIA:
1942 atomic_inc_32(&bd->d_kerr->bd_rq_media_err.value.ui32);
1943 break;
1944 case BD_ERR_NTRDY:
1945 atomic_inc_32(&bd->d_kerr->bd_rq_ntrdy_err.value.ui32);
1946 break;
1947 case BD_ERR_NODEV:
1948 atomic_inc_32(&bd->d_kerr->bd_rq_nodev_err.value.ui32);
1949 break;
1950 case BD_ERR_RECOV:
1951 atomic_inc_32(&bd->d_kerr->bd_rq_recov_err.value.ui32);
1952 break;
1953 case BD_ERR_ILLRQ:
1954 atomic_inc_32(&bd->d_kerr->bd_rq_illrq_err.value.ui32);
1955 break;
1956 case BD_ERR_PFA:
1957 atomic_inc_32(&bd->d_kerr->bd_rq_pfa_err.value.ui32);
1958 break;
1959 default:
1960 cmn_err(CE_PANIC, "bd_error: unknown error type %d", error);
1961 break;
1962 }
1963 }
1964
1965 void
1966 bd_state_change(bd_handle_t hdl)
1967 {
1968 bd_t *bd;
1969
1970 if ((bd = hdl->h_bd) != NULL) {
1971 bd_update_state(bd);
1972 }
1973 }
1974
1975 void
1976 bd_mod_init(struct dev_ops *devops)
1977 {
1978 static struct bus_ops bd_bus_ops = {
1979 BUSO_REV, /* busops_rev */
1980 nullbusmap, /* bus_map */
1981 NULL, /* bus_get_intrspec (OBSOLETE) */
1982 NULL, /* bus_add_intrspec (OBSOLETE) */
1983 NULL, /* bus_remove_intrspec (OBSOLETE) */
1984 i_ddi_map_fault, /* bus_map_fault */
1985 NULL, /* bus_dma_map (OBSOLETE) */
1986 ddi_dma_allochdl, /* bus_dma_allochdl */
1987 ddi_dma_freehdl, /* bus_dma_freehdl */
1988 ddi_dma_bindhdl, /* bus_dma_bindhdl */
1989 ddi_dma_unbindhdl, /* bus_dma_unbindhdl */
1990 ddi_dma_flush, /* bus_dma_flush */
1991 ddi_dma_win, /* bus_dma_win */
1992 ddi_dma_mctl, /* bus_dma_ctl */
1993 bd_bus_ctl, /* bus_ctl */
1994 ddi_bus_prop_op, /* bus_prop_op */
1995 NULL, /* bus_get_eventcookie */
1996 NULL, /* bus_add_eventcall */
1997 NULL, /* bus_remove_eventcall */
1998 NULL, /* bus_post_event */
1999 NULL, /* bus_intr_ctl (OBSOLETE) */
2000 NULL, /* bus_config */
2001 NULL, /* bus_unconfig */
2002 NULL, /* bus_fm_init */
2003 NULL, /* bus_fm_fini */
2004 NULL, /* bus_fm_access_enter */
2005 NULL, /* bus_fm_access_exit */
2006 NULL, /* bus_power */
2007 NULL, /* bus_intr_op */
2008 };
2009
2010 devops->devo_bus_ops = &bd_bus_ops;
2011
2012 /*
2013 * NB: The device driver is free to supply its own
2014 * character entry device support.
2015 */
2016 }
2017
2018 void
2019 bd_mod_fini(struct dev_ops *devops)
2020 {
2021 devops->devo_bus_ops = NULL;
2022 }