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