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