ps3cdrom.c revision 298230
1/*- 2 * Copyright (C) 2011 glevand <geoffrey.levand@mail.ru> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * $FreeBSD: head/sys/boot/powerpc/ps3/ps3cdrom.c 298230 2016-04-18 23:09:22Z allanjude $ 26 */ 27 28#include <sys/param.h> 29#include <sys/endian.h> 30#include <machine/stdarg.h> 31#include <stand.h> 32 33#include "bootstrap.h" 34#include "ps3bus.h" 35#include "ps3devdesc.h" 36#include "ps3stor.h" 37 38#define dev_printf(dev, fmt, args...) \ 39 printf("%s%d: " fmt "\n", dev->d_dev->dv_name, dev->d_unit, ##args) 40 41#ifdef CD_DEBUG 42#define DEBUG(fmt, args...) printf("%s:%d: " fmt "\n", __func__, __LINE__, ##args) 43#else 44#define DEBUG(fmt, args...) 45#endif 46 47static int ps3cdrom_init(void); 48static int ps3cdrom_strategy(void *devdata, int flag, daddr_t dblk, 49 size_t offset, size_t size, char *buf, size_t *rsize); 50static int ps3cdrom_open(struct open_file *f, ...); 51static int ps3cdrom_close(struct open_file *f); 52static void ps3cdrom_print(int verbose); 53 54struct devsw ps3cdrom = { 55 "cd", 56 DEVT_CD, 57 ps3cdrom_init, 58 ps3cdrom_strategy, 59 ps3cdrom_open, 60 ps3cdrom_close, 61 noioctl, 62 ps3cdrom_print, 63}; 64 65static struct ps3_stordev stor_dev; 66 67static int ps3cdrom_init(void) 68{ 69 int err; 70 71 err = ps3stor_setup(&stor_dev, PS3_DEV_TYPE_STOR_CDROM); 72 if (err) 73 return err; 74 75 return 0; 76} 77 78static int ps3cdrom_strategy(void *devdata, int flag, daddr_t dblk, 79 size_t offset, size_t size, char *buf, size_t *rsize) 80{ 81 struct ps3_devdesc *dev = (struct ps3_devdesc *) devdata; 82 int err; 83 84 DEBUG("d_unit=%u dblk=%llu size=%u", dev->d_unit, dblk, size); 85 86 if (flag != F_READ) { 87 dev_printf(dev, "write operation is not supported!"); 88 return EROFS; 89 } 90 91 if (dblk % (stor_dev.sd_blksize / DEV_BSIZE) != 0) 92 return EINVAL; 93 94 dblk /= (stor_dev.sd_blksize / DEV_BSIZE); 95 96 if (size % stor_dev.sd_blksize) { 97 dev_printf(dev, 98 "size=%u is not multiple of device block size=%llu", size, 99 stor_dev.sd_blksize); 100 return EINVAL; 101 } 102 103 if (rsize) 104 *rsize = 0; 105 106 err = ps3stor_read_sectors(&stor_dev, dev->d_unit, dblk, 107 size / stor_dev.sd_blksize, 0, buf); 108 109 if (!err && rsize) 110 *rsize = size; 111 112 if (err) 113 dev_printf(dev, 114 "read operation failed dblk=%llu size=%d err=%d", dblk, 115 size, err); 116 117 return err; 118} 119 120static int ps3cdrom_open(struct open_file *f, ...) 121{ 122 char buf[2048]; 123 va_list ap; 124 struct ps3_devdesc *dev; 125 int err; 126 127 va_start(ap, f); 128 dev = va_arg(ap, struct ps3_devdesc *); 129 va_end(ap); 130 131 if (dev->d_unit > 0) { 132 dev_printf(dev, "attempt to open nonexistent disk"); 133 return ENXIO; 134 } 135 136 err = ps3stor_read_sectors(&stor_dev, dev->d_unit, 16, 1, 0, buf); 137 if (err) 138 return EIO; 139 140 /* Do not attach if not ISO9660 (workaround for buggy firmware) */ 141 if (memcmp(buf, "\001CD001", 6) != 0) 142 return EIO; 143 144 return 0; 145} 146 147static int ps3cdrom_close(struct open_file *f) 148{ 149 return 0; 150} 151 152static void ps3cdrom_print(int verbose) 153{ 154} 155