1224857Snwhitehorn/*- 2224857Snwhitehorn * Copyright (C) 2011 glevand <geoffrey.levand@mail.ru> 3224857Snwhitehorn * All rights reserved. 4224857Snwhitehorn * 5224857Snwhitehorn * Redistribution and use in source and binary forms, with or without 6224857Snwhitehorn * modification, are permitted provided that the following conditions 7224857Snwhitehorn * are met: 8224857Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9224857Snwhitehorn * notice, this list of conditions and the following disclaimer. 10224857Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11224857Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12224857Snwhitehorn * documentation and/or other materials provided with the distribution. 13224857Snwhitehorn * 14224857Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15224857Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16224857Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17224857Snwhitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18224857Snwhitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19224857Snwhitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20224857Snwhitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21224857Snwhitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22224857Snwhitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23224857Snwhitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24224857Snwhitehorn * 25224857Snwhitehorn * $FreeBSD: releng/11.0/sys/boot/powerpc/ps3/ps3cdrom.c 298230 2016-04-18 23:09:22Z allanjude $ 26224857Snwhitehorn */ 27224857Snwhitehorn 28224857Snwhitehorn#include <sys/param.h> 29224857Snwhitehorn#include <sys/endian.h> 30224857Snwhitehorn#include <machine/stdarg.h> 31224857Snwhitehorn#include <stand.h> 32224857Snwhitehorn 33224857Snwhitehorn#include "bootstrap.h" 34224857Snwhitehorn#include "ps3bus.h" 35224857Snwhitehorn#include "ps3devdesc.h" 36224857Snwhitehorn#include "ps3stor.h" 37224857Snwhitehorn 38224857Snwhitehorn#define dev_printf(dev, fmt, args...) \ 39224857Snwhitehorn printf("%s%d: " fmt "\n", dev->d_dev->dv_name, dev->d_unit, ##args) 40224857Snwhitehorn 41224857Snwhitehorn#ifdef CD_DEBUG 42224857Snwhitehorn#define DEBUG(fmt, args...) printf("%s:%d: " fmt "\n", __func__, __LINE__, ##args) 43224857Snwhitehorn#else 44224857Snwhitehorn#define DEBUG(fmt, args...) 45224857Snwhitehorn#endif 46224857Snwhitehorn 47224857Snwhitehornstatic int ps3cdrom_init(void); 48224857Snwhitehornstatic int ps3cdrom_strategy(void *devdata, int flag, daddr_t dblk, 49298230Sallanjude size_t offset, size_t size, char *buf, size_t *rsize); 50224857Snwhitehornstatic int ps3cdrom_open(struct open_file *f, ...); 51224857Snwhitehornstatic int ps3cdrom_close(struct open_file *f); 52224857Snwhitehornstatic void ps3cdrom_print(int verbose); 53224857Snwhitehorn 54224857Snwhitehornstruct devsw ps3cdrom = { 55224857Snwhitehorn "cd", 56224857Snwhitehorn DEVT_CD, 57224857Snwhitehorn ps3cdrom_init, 58224857Snwhitehorn ps3cdrom_strategy, 59224857Snwhitehorn ps3cdrom_open, 60224857Snwhitehorn ps3cdrom_close, 61224857Snwhitehorn noioctl, 62224857Snwhitehorn ps3cdrom_print, 63224857Snwhitehorn}; 64224857Snwhitehorn 65224857Snwhitehornstatic struct ps3_stordev stor_dev; 66224857Snwhitehorn 67224857Snwhitehornstatic int ps3cdrom_init(void) 68224857Snwhitehorn{ 69224857Snwhitehorn int err; 70224857Snwhitehorn 71224857Snwhitehorn err = ps3stor_setup(&stor_dev, PS3_DEV_TYPE_STOR_CDROM); 72224857Snwhitehorn if (err) 73224857Snwhitehorn return err; 74224857Snwhitehorn 75224857Snwhitehorn return 0; 76224857Snwhitehorn} 77224857Snwhitehorn 78224857Snwhitehornstatic int ps3cdrom_strategy(void *devdata, int flag, daddr_t dblk, 79298230Sallanjude size_t offset, size_t size, char *buf, size_t *rsize) 80224857Snwhitehorn{ 81224857Snwhitehorn struct ps3_devdesc *dev = (struct ps3_devdesc *) devdata; 82224857Snwhitehorn int err; 83224857Snwhitehorn 84224857Snwhitehorn DEBUG("d_unit=%u dblk=%llu size=%u", dev->d_unit, dblk, size); 85224857Snwhitehorn 86224857Snwhitehorn if (flag != F_READ) { 87224857Snwhitehorn dev_printf(dev, "write operation is not supported!"); 88224857Snwhitehorn return EROFS; 89224857Snwhitehorn } 90224857Snwhitehorn 91224857Snwhitehorn if (dblk % (stor_dev.sd_blksize / DEV_BSIZE) != 0) 92224857Snwhitehorn return EINVAL; 93224857Snwhitehorn 94224857Snwhitehorn dblk /= (stor_dev.sd_blksize / DEV_BSIZE); 95224857Snwhitehorn 96224857Snwhitehorn if (size % stor_dev.sd_blksize) { 97224857Snwhitehorn dev_printf(dev, 98224857Snwhitehorn "size=%u is not multiple of device block size=%llu", size, 99224857Snwhitehorn stor_dev.sd_blksize); 100224857Snwhitehorn return EINVAL; 101224857Snwhitehorn } 102224857Snwhitehorn 103224857Snwhitehorn if (rsize) 104224857Snwhitehorn *rsize = 0; 105224857Snwhitehorn 106224857Snwhitehorn err = ps3stor_read_sectors(&stor_dev, dev->d_unit, dblk, 107224857Snwhitehorn size / stor_dev.sd_blksize, 0, buf); 108224857Snwhitehorn 109224857Snwhitehorn if (!err && rsize) 110224857Snwhitehorn *rsize = size; 111224857Snwhitehorn 112224857Snwhitehorn if (err) 113224857Snwhitehorn dev_printf(dev, 114224857Snwhitehorn "read operation failed dblk=%llu size=%d err=%d", dblk, 115224857Snwhitehorn size, err); 116224857Snwhitehorn 117224857Snwhitehorn return err; 118224857Snwhitehorn} 119224857Snwhitehorn 120224857Snwhitehornstatic int ps3cdrom_open(struct open_file *f, ...) 121224857Snwhitehorn{ 122224857Snwhitehorn char buf[2048]; 123224857Snwhitehorn va_list ap; 124224857Snwhitehorn struct ps3_devdesc *dev; 125224857Snwhitehorn int err; 126224857Snwhitehorn 127224857Snwhitehorn va_start(ap, f); 128224857Snwhitehorn dev = va_arg(ap, struct ps3_devdesc *); 129224857Snwhitehorn va_end(ap); 130224857Snwhitehorn 131224857Snwhitehorn if (dev->d_unit > 0) { 132224857Snwhitehorn dev_printf(dev, "attempt to open nonexistent disk"); 133224857Snwhitehorn return ENXIO; 134224857Snwhitehorn } 135224857Snwhitehorn 136224857Snwhitehorn err = ps3stor_read_sectors(&stor_dev, dev->d_unit, 16, 1, 0, buf); 137224857Snwhitehorn if (err) 138224857Snwhitehorn return EIO; 139224857Snwhitehorn 140224857Snwhitehorn /* Do not attach if not ISO9660 (workaround for buggy firmware) */ 141224857Snwhitehorn if (memcmp(buf, "\001CD001", 6) != 0) 142224857Snwhitehorn return EIO; 143224857Snwhitehorn 144224857Snwhitehorn return 0; 145224857Snwhitehorn} 146224857Snwhitehorn 147224857Snwhitehornstatic int ps3cdrom_close(struct open_file *f) 148224857Snwhitehorn{ 149224857Snwhitehorn return 0; 150224857Snwhitehorn} 151224857Snwhitehorn 152224857Snwhitehornstatic void ps3cdrom_print(int verbose) 153224857Snwhitehorn{ 154224857Snwhitehorn} 155