1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2011 glevand ([email protected])
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/sysctl.h>
33 #include <sys/disk.h>
34 #include <sys/bio.h>
35 #include <sys/bus.h>
36 #include <sys/conf.h>
37 #include <sys/kernel.h>
38 #include <sys/kthread.h>
39 #include <sys/lock.h>
40 #include <sys/malloc.h>
41 #include <sys/module.h>
42 #include <sys/mutex.h>
43
44 #include <vm/vm.h>
45 #include <vm/pmap.h>
46
47 #include <machine/pio.h>
48 #include <machine/bus.h>
49 #include <machine/platform.h>
50 #include <machine/resource.h>
51 #include <sys/bus.h>
52 #include <sys/rman.h>
53
54 #include <geom/geom_disk.h>
55
56 #include "ps3bus.h"
57 #include "ps3-hvcall.h"
58
59 #define PS3DISK_LOCK_INIT(_sc) \
60 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), "ps3disk", MTX_DEF)
61 #define PS3DISK_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
62 #define PS3DISK_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
63 #define PS3DISK_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
64 #define PS3DISK_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
65 #define PS3DISK_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
66
67 #define LV1_STORAGE_ATA_HDDOUT 0x23
68
69 static SYSCTL_NODE(_hw, OID_AUTO, ps3disk, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
70 "PS3 Disk driver parameters");
71
72 #ifdef PS3DISK_DEBUG
73 static int ps3disk_debug = 0;
74 SYSCTL_INT(_hw_ps3disk, OID_AUTO, debug, CTLFLAG_RW, &ps3disk_debug,
75 0, "control debugging printfs");
76 TUNABLE_INT("hw.ps3disk.debug", &ps3disk_debug);
77 enum {
78 PS3DISK_DEBUG_INTR = 0x00000001,
79 PS3DISK_DEBUG_TASK = 0x00000002,
80 PS3DISK_DEBUG_READ = 0x00000004,
81 PS3DISK_DEBUG_WRITE = 0x00000008,
82 PS3DISK_DEBUG_FLUSH = 0x00000010,
83 PS3DISK_DEBUG_ANY = 0xffffffff
84 };
85 #define DPRINTF(sc, m, fmt, ...) \
86 do { \
87 if (sc->sc_debug & (m)) \
88 printf(fmt, __VA_ARGS__); \
89 } while (0)
90 #else
91 #define DPRINTF(sc, m, fmt, ...)
92 #endif
93
94 struct ps3disk_region {
95 uint64_t r_id;
96 uint64_t r_start;
97 uint64_t r_size;
98 uint64_t r_flags;
99 };
100
101 struct ps3disk_softc {
102 device_t sc_dev;
103
104 struct mtx sc_mtx;
105
106 uint64_t sc_blksize;
107 uint64_t sc_nblocks;
108
109 uint64_t sc_nregs;
110 struct ps3disk_region *sc_reg;
111
112 int sc_irqid;
113 struct resource *sc_irq;
114 void *sc_irqctx;
115
116 struct disk **sc_disk;
117
118 struct bio_queue_head sc_bioq;
119 struct bio_queue_head sc_deferredq;
120 struct proc *sc_task;
121
122 bus_dma_tag_t sc_dmatag;
123
124 int sc_running;
125 int sc_debug;
126 };
127
128 static int ps3disk_open(struct disk *dp);
129 static int ps3disk_close(struct disk *dp);
130 static void ps3disk_strategy(struct bio *bp);
131
132 static void ps3disk_task(void *arg);
133 static void ps3disk_intr(void *arg);
134 static int ps3disk_get_disk_geometry(struct ps3disk_softc *sc);
135 static int ps3disk_enum_regions(struct ps3disk_softc *sc);
136 static void ps3disk_transfer(void *arg, bus_dma_segment_t *segs, int nsegs,
137 int error);
138
139 static void ps3disk_sysctlattach(struct ps3disk_softc *sc);
140
141 static MALLOC_DEFINE(M_PS3DISK, "ps3disk", "PS3 Disk");
142
143 static int
ps3disk_probe(device_t dev)144 ps3disk_probe(device_t dev)
145 {
146 if (ps3bus_get_bustype(dev) != PS3_BUSTYPE_STORAGE ||
147 ps3bus_get_devtype(dev) != PS3_DEVTYPE_DISK)
148 return (ENXIO);
149
150 device_set_desc(dev, "Playstation 3 Disk");
151
152 return (BUS_PROBE_SPECIFIC);
153 }
154
155 static int
ps3disk_attach(device_t dev)156 ps3disk_attach(device_t dev)
157 {
158 struct ps3disk_softc *sc;
159 struct disk *d;
160 intmax_t mb;
161 uint64_t junk;
162 char unit;
163 int i, err;
164
165 sc = device_get_softc(dev);
166 sc->sc_dev = dev;
167
168 PS3DISK_LOCK_INIT(sc);
169
170 err = ps3disk_get_disk_geometry(sc);
171 if (err) {
172 device_printf(dev, "Could not get disk geometry\n");
173 err = ENXIO;
174 goto fail_destroy_lock;
175 }
176
177 device_printf(dev, "block size %lu total blocks %lu\n",
178 sc->sc_blksize, sc->sc_nblocks);
179
180 err = ps3disk_enum_regions(sc);
181 if (err) {
182 device_printf(dev, "Could not enumerate disk regions\n");
183 err = ENXIO;
184 goto fail_destroy_lock;
185 }
186
187 device_printf(dev, "Found %lu regions\n", sc->sc_nregs);
188
189 if (!sc->sc_nregs) {
190 err = ENXIO;
191 goto fail_destroy_lock;
192 }
193
194 /* Setup interrupt handler */
195 sc->sc_irqid = 0;
196 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqid,
197 RF_ACTIVE);
198 if (!sc->sc_irq) {
199 device_printf(dev, "Could not allocate IRQ\n");
200 err = ENXIO;
201 goto fail_free_regions;
202 }
203
204 err = bus_setup_intr(dev, sc->sc_irq,
205 INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
206 NULL, ps3disk_intr, sc, &sc->sc_irqctx);
207 if (err) {
208 device_printf(dev, "Could not setup IRQ\n");
209 err = ENXIO;
210 goto fail_release_intr;
211 }
212
213 /* Setup DMA */
214 err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0,
215 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
216 BUS_SPACE_UNRESTRICTED, 1, PAGE_SIZE, 0,
217 busdma_lock_mutex, &sc->sc_mtx, &sc->sc_dmatag);
218 if (err) {
219 device_printf(dev, "Could not create DMA tag\n");
220 err = ENXIO;
221 goto fail_teardown_intr;
222 }
223
224 /* Setup disks */
225
226 sc->sc_disk = malloc(sc->sc_nregs * sizeof(struct disk *),
227 M_PS3DISK, M_ZERO | M_WAITOK);
228 if (!sc->sc_disk) {
229 device_printf(dev, "Could not allocate disk(s)\n");
230 err = ENOMEM;
231 goto fail_teardown_intr;
232 }
233
234 for (i = 0; i < sc->sc_nregs; i++) {
235 struct ps3disk_region *rp = &sc->sc_reg[i];
236
237 d = sc->sc_disk[i] = disk_alloc();
238 d->d_open = ps3disk_open;
239 d->d_close = ps3disk_close;
240 d->d_strategy = ps3disk_strategy;
241 d->d_name = "ps3disk";
242 d->d_drv1 = sc;
243 d->d_maxsize = PAGE_SIZE;
244 d->d_sectorsize = sc->sc_blksize;
245 d->d_unit = i;
246 d->d_mediasize = sc->sc_reg[i].r_size * sc->sc_blksize;
247 d->d_flags |= DISKFLAG_CANFLUSHCACHE;
248
249 mb = d->d_mediasize >> 20;
250 unit = 'M';
251 if (mb >= 10240) {
252 unit = 'G';
253 mb /= 1024;
254 }
255
256 /* Test to see if we can read this region */
257 err = lv1_storage_read(ps3bus_get_device(dev), d->d_unit,
258 0, 0, rp->r_flags, 0, &junk);
259 device_printf(dev, "region %d %ju%cB%s\n", i, mb, unit,
260 (err == LV1_DENIED_BY_POLICY) ? " (hypervisor protected)"
261 : "");
262
263 if (err != LV1_DENIED_BY_POLICY)
264 disk_create(d, DISK_VERSION);
265 }
266 err = 0;
267
268 bioq_init(&sc->sc_bioq);
269 bioq_init(&sc->sc_deferredq);
270 kproc_create(&ps3disk_task, sc, &sc->sc_task, 0, 0, "ps3disk");
271
272 ps3disk_sysctlattach(sc);
273 sc->sc_running = 1;
274 return (0);
275
276 fail_teardown_intr:
277 bus_teardown_intr(dev, sc->sc_irq, sc->sc_irqctx);
278 fail_release_intr:
279 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqid, sc->sc_irq);
280 fail_free_regions:
281 free(sc->sc_reg, M_PS3DISK);
282 fail_destroy_lock:
283 PS3DISK_LOCK_DESTROY(sc);
284 return (err);
285 }
286
287 static int
ps3disk_detach(device_t dev)288 ps3disk_detach(device_t dev)
289 {
290 struct ps3disk_softc *sc = device_get_softc(dev);
291 int i;
292
293 for (i = 0; i < sc->sc_nregs; i++)
294 disk_destroy(sc->sc_disk[i]);
295
296 bus_dma_tag_destroy(sc->sc_dmatag);
297
298 bus_teardown_intr(dev, sc->sc_irq, sc->sc_irqctx);
299 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqid, sc->sc_irq);
300
301 free(sc->sc_disk, M_PS3DISK);
302 free(sc->sc_reg, M_PS3DISK);
303
304 PS3DISK_LOCK_DESTROY(sc);
305
306 return (0);
307 }
308
309 static int
ps3disk_open(struct disk * dp)310 ps3disk_open(struct disk *dp)
311 {
312 return (0);
313 }
314
315 static int
ps3disk_close(struct disk * dp)316 ps3disk_close(struct disk *dp)
317 {
318 return (0);
319 }
320
321 /* Process deferred blocks */
322 static void
ps3disk_task(void * arg)323 ps3disk_task(void *arg)
324 {
325 struct ps3disk_softc *sc = (struct ps3disk_softc *) arg;
326 struct bio *bp;
327
328 while (1) {
329 kproc_suspend_check(sc->sc_task);
330 tsleep(&sc->sc_deferredq, PRIBIO, "ps3disk", 10);
331
332 PS3DISK_LOCK(sc);
333 bp = bioq_takefirst(&sc->sc_deferredq);
334 PS3DISK_UNLOCK(sc);
335
336 if (bp == NULL)
337 continue;
338
339 if (bp->bio_driver1 != NULL) {
340 bus_dmamap_unload(sc->sc_dmatag, (bus_dmamap_t)
341 bp->bio_driver1);
342 bus_dmamap_destroy(sc->sc_dmatag, (bus_dmamap_t)
343 bp->bio_driver1);
344 }
345
346 ps3disk_strategy(bp);
347 }
348
349 kproc_exit(0);
350 }
351
352 static void
ps3disk_strategy(struct bio * bp)353 ps3disk_strategy(struct bio *bp)
354 {
355 struct ps3disk_softc *sc = (struct ps3disk_softc *)bp->bio_disk->d_drv1;
356 int err;
357
358 if (sc == NULL) {
359 bp->bio_flags |= BIO_ERROR;
360 bp->bio_error = EINVAL;
361 biodone(bp);
362 return;
363 }
364
365 PS3DISK_LOCK(sc);
366 bp->bio_resid = bp->bio_bcount;
367 bioq_insert_tail(&sc->sc_bioq, bp);
368
369 DPRINTF(sc, PS3DISK_DEBUG_TASK, "%s: bio_cmd 0x%02x\n",
370 __func__, bp->bio_cmd);
371
372 err = 0;
373 if (bp->bio_cmd == BIO_FLUSH) {
374 bp->bio_driver1 = 0;
375 err = lv1_storage_send_device_command(
376 ps3bus_get_device(sc->sc_dev), LV1_STORAGE_ATA_HDDOUT,
377 0, 0, 0, 0, (uint64_t *)&bp->bio_driver2);
378 if (err == LV1_BUSY)
379 err = EAGAIN;
380 } else if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
381 if (bp->bio_bcount % sc->sc_blksize != 0) {
382 err = EINVAL;
383 } else {
384 bus_dmamap_create(sc->sc_dmatag, BUS_DMA_COHERENT,
385 (bus_dmamap_t *)(&bp->bio_driver1));
386 err = bus_dmamap_load(sc->sc_dmatag,
387 (bus_dmamap_t)(bp->bio_driver1), bp->bio_data,
388 bp->bio_bcount, ps3disk_transfer, bp, 0);
389 if (err == EINPROGRESS)
390 err = 0;
391 }
392 } else {
393 err = EINVAL;
394 }
395
396 if (err == EAGAIN) {
397 bioq_remove(&sc->sc_bioq, bp);
398 bioq_insert_tail(&sc->sc_deferredq, bp);
399 } else if (err != 0) {
400 bp->bio_error = err;
401 bp->bio_flags |= BIO_ERROR;
402 bioq_remove(&sc->sc_bioq, bp);
403 disk_err(bp, "hard error", -1, 1);
404 biodone(bp);
405 }
406
407 PS3DISK_UNLOCK(sc);
408 }
409
410 static void
ps3disk_intr(void * arg)411 ps3disk_intr(void *arg)
412 {
413 struct ps3disk_softc *sc = (struct ps3disk_softc *) arg;
414 device_t dev = sc->sc_dev;
415 uint64_t devid = ps3bus_get_device(dev);
416 struct bio *bp;
417 uint64_t tag, status;
418
419 if (lv1_storage_get_async_status(devid, &tag, &status) != 0)
420 return;
421
422 PS3DISK_LOCK(sc);
423
424 DPRINTF(sc, PS3DISK_DEBUG_INTR, "%s: tag 0x%016lx "
425 "status 0x%016lx\n", __func__, tag, status);
426
427 /* Locate the matching request */
428 TAILQ_FOREACH(bp, &sc->sc_bioq.queue, bio_queue) {
429 if ((uint64_t)bp->bio_driver2 != tag)
430 continue;
431
432 if (status != 0) {
433 device_printf(sc->sc_dev, "%s error (%#lx)\n",
434 (bp->bio_cmd == BIO_READ) ? "Read" : "Write",
435 status);
436 bp->bio_error = EIO;
437 bp->bio_flags |= BIO_ERROR;
438 } else {
439 bp->bio_error = 0;
440 bp->bio_resid = 0;
441 bp->bio_flags |= BIO_DONE;
442 }
443
444 if (bp->bio_driver1 != NULL) {
445 if (bp->bio_cmd == BIO_READ)
446 bus_dmamap_sync(sc->sc_dmatag, (bus_dmamap_t)
447 bp->bio_driver1, BUS_DMASYNC_POSTREAD);
448 bus_dmamap_unload(sc->sc_dmatag, (bus_dmamap_t)
449 bp->bio_driver1);
450 bus_dmamap_destroy(sc->sc_dmatag, (bus_dmamap_t)
451 bp->bio_driver1);
452 }
453
454 bioq_remove(&sc->sc_bioq, bp);
455 biodone(bp);
456 break;
457 }
458
459 if (bioq_first(&sc->sc_deferredq) != NULL)
460 wakeup(&sc->sc_deferredq);
461
462 PS3DISK_UNLOCK(sc);
463 }
464
465 static int
ps3disk_get_disk_geometry(struct ps3disk_softc * sc)466 ps3disk_get_disk_geometry(struct ps3disk_softc *sc)
467 {
468 device_t dev = sc->sc_dev;
469 uint64_t bus_index = ps3bus_get_busidx(dev);
470 uint64_t dev_index = ps3bus_get_devidx(dev);
471 uint64_t junk;
472 int err;
473
474 err = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
475 (lv1_repository_string("bus") >> 32) | bus_index,
476 lv1_repository_string("dev") | dev_index,
477 lv1_repository_string("blk_size"), 0, &sc->sc_blksize, &junk);
478 if (err) {
479 device_printf(dev, "Could not get block size (0x%08x)\n", err);
480 return (ENXIO);
481 }
482
483 err = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
484 (lv1_repository_string("bus") >> 32) | bus_index,
485 lv1_repository_string("dev") | dev_index,
486 lv1_repository_string("n_blocks"), 0, &sc->sc_nblocks, &junk);
487 if (err) {
488 device_printf(dev, "Could not get total number of blocks "
489 "(0x%08x)\n", err);
490 err = ENXIO;
491 }
492
493 return (err);
494 }
495
496 static int
ps3disk_enum_regions(struct ps3disk_softc * sc)497 ps3disk_enum_regions(struct ps3disk_softc *sc)
498 {
499 device_t dev = sc->sc_dev;
500 uint64_t bus_index = ps3bus_get_busidx(dev);
501 uint64_t dev_index = ps3bus_get_devidx(dev);
502 uint64_t junk;
503 int i, err;
504
505 /* Read number of regions */
506
507 err = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
508 (lv1_repository_string("bus") >> 32) | bus_index,
509 lv1_repository_string("dev") | dev_index,
510 lv1_repository_string("n_regs"), 0, &sc->sc_nregs, &junk);
511 if (err) {
512 device_printf(dev, "Could not get number of regions (0x%08x)\n",
513 err);
514 err = ENXIO;
515 goto fail;
516 }
517
518 if (!sc->sc_nregs)
519 return 0;
520
521 sc->sc_reg = malloc(sc->sc_nregs * sizeof(struct ps3disk_region),
522 M_PS3DISK, M_ZERO | M_WAITOK);
523 if (!sc->sc_reg) {
524 err = ENOMEM;
525 goto fail;
526 }
527
528 /* Setup regions */
529
530 for (i = 0; i < sc->sc_nregs; i++) {
531 err = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
532 (lv1_repository_string("bus") >> 32) | bus_index,
533 lv1_repository_string("dev") | dev_index,
534 lv1_repository_string("region") | i,
535 lv1_repository_string("id"), &sc->sc_reg[i].r_id, &junk);
536 if (err) {
537 device_printf(dev, "Could not get region id (0x%08x)\n",
538 err);
539 err = ENXIO;
540 goto fail;
541 }
542
543 err = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
544 (lv1_repository_string("bus") >> 32) | bus_index,
545 lv1_repository_string("dev") | dev_index,
546 lv1_repository_string("region") | i,
547 lv1_repository_string("start"), &sc->sc_reg[i].r_start,
548 &junk);
549 if (err) {
550 device_printf(dev, "Could not get region start "
551 "(0x%08x)\n", err);
552 err = ENXIO;
553 goto fail;
554 }
555
556 err = lv1_get_repository_node_value(PS3_LPAR_ID_PME,
557 (lv1_repository_string("bus") >> 32) | bus_index,
558 lv1_repository_string("dev") | dev_index,
559 lv1_repository_string("region") | i,
560 lv1_repository_string("size"), &sc->sc_reg[i].r_size,
561 &junk);
562 if (err) {
563 device_printf(dev, "Could not get region size "
564 "(0x%08x)\n", err);
565 err = ENXIO;
566 goto fail;
567 }
568
569 if (i == 0)
570 sc->sc_reg[i].r_flags = 0x2;
571 else
572 sc->sc_reg[i].r_flags = 0;
573 }
574
575 return (0);
576
577 fail:
578
579 sc->sc_nregs = 0;
580 if (sc->sc_reg)
581 free(sc->sc_reg, M_PS3DISK);
582
583 return (err);
584 }
585
586 static void
ps3disk_transfer(void * arg,bus_dma_segment_t * segs,int nsegs,int error)587 ps3disk_transfer(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
588 {
589 struct bio *bp = (struct bio *)(arg);
590 struct ps3disk_softc *sc = (struct ps3disk_softc *)bp->bio_disk->d_drv1;
591 struct ps3disk_region *rp = &sc->sc_reg[bp->bio_disk->d_unit];
592 uint64_t devid = ps3bus_get_device(sc->sc_dev);
593 uint64_t block;
594 int i, err;
595
596 /* Locks already held by busdma */
597 PS3DISK_ASSERT_LOCKED(sc);
598
599 if (error) {
600 bp->bio_error = error;
601 bp->bio_flags |= BIO_ERROR;
602 bioq_remove(&sc->sc_bioq, bp);
603 biodone(bp);
604 return;
605 }
606
607 block = bp->bio_pblkno;
608 for (i = 0; i < nsegs; i++) {
609 KASSERT((segs[i].ds_len % sc->sc_blksize) == 0,
610 ("DMA fragments not blocksize multiples"));
611
612 if (bp->bio_cmd == BIO_READ) {
613 err = lv1_storage_read(devid, rp->r_id,
614 block, segs[i].ds_len/sc->sc_blksize,
615 rp->r_flags, segs[i].ds_addr,
616 (uint64_t *)&bp->bio_driver2);
617 } else {
618 bus_dmamap_sync(sc->sc_dmatag,
619 (bus_dmamap_t)bp->bio_driver1,
620 BUS_DMASYNC_PREWRITE);
621 err = lv1_storage_write(devid, rp->r_id,
622 block, segs[i].ds_len/sc->sc_blksize,
623 rp->r_flags, segs[i].ds_addr,
624 (uint64_t *)&bp->bio_driver2);
625 }
626
627 if (err) {
628 if (err == LV1_BUSY) {
629 bioq_remove(&sc->sc_bioq, bp);
630 bioq_insert_tail(&sc->sc_deferredq, bp);
631 } else {
632 bus_dmamap_unload(sc->sc_dmatag, (bus_dmamap_t)
633 bp->bio_driver1);
634 bus_dmamap_destroy(sc->sc_dmatag, (bus_dmamap_t)
635 bp->bio_driver1);
636 device_printf(sc->sc_dev, "Could not read "
637 "sectors (0x%08x)\n", err);
638 bp->bio_error = EINVAL;
639 bp->bio_flags |= BIO_ERROR;
640 bioq_remove(&sc->sc_bioq, bp);
641 biodone(bp);
642 }
643
644 break;
645 }
646
647 DPRINTF(sc, PS3DISK_DEBUG_READ, "%s: tag 0x%016lx\n",
648 __func__, sc->sc_bounce_tag);
649 }
650 }
651
652 #ifdef PS3DISK_DEBUG
653 static int
ps3disk_sysctl_debug(SYSCTL_HANDLER_ARGS)654 ps3disk_sysctl_debug(SYSCTL_HANDLER_ARGS)
655 {
656 struct ps3disk_softc *sc = arg1;
657 int debug, error;
658
659 debug = sc->sc_debug;
660
661 error = sysctl_handle_int(oidp, &debug, 0, req);
662 if (error || !req->newptr)
663 return error;
664
665 sc->sc_debug = debug;
666
667 return 0;
668 }
669 #endif
670
671 static void
ps3disk_sysctlattach(struct ps3disk_softc * sc)672 ps3disk_sysctlattach(struct ps3disk_softc *sc)
673 {
674 #ifdef PS3DISK_DEBUG
675 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
676 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
677
678 sc->sc_debug = ps3disk_debug;
679
680 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
681 "debug", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0,
682 ps3disk_sysctl_debug, "I", "control debugging printfs");
683 #endif
684 }
685
686 static device_method_t ps3disk_methods[] = {
687 DEVMETHOD(device_probe, ps3disk_probe),
688 DEVMETHOD(device_attach, ps3disk_attach),
689 DEVMETHOD(device_detach, ps3disk_detach),
690 {0, 0},
691 };
692
693 static driver_t ps3disk_driver = {
694 "ps3disk",
695 ps3disk_methods,
696 sizeof(struct ps3disk_softc),
697 };
698
699 DRIVER_MODULE(ps3disk, ps3bus, ps3disk_driver, 0, 0);
700