1223314Snwhitehorn/*- 2223314Snwhitehorn * Copyright (C) 2010 Nathan Whitehorn 3223314Snwhitehorn * All rights reserved. 4223314Snwhitehorn * 5223314Snwhitehorn * Redistribution and use in source and binary forms, with or without 6223314Snwhitehorn * modification, are permitted provided that the following conditions 7223314Snwhitehorn * are met: 8223314Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9223314Snwhitehorn * notice, this list of conditions and the following disclaimer. 10223314Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11223314Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12223314Snwhitehorn * documentation and/or other materials provided with the distribution. 13223314Snwhitehorn * 14223314Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15223314Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16223314Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17223314Snwhitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18223314Snwhitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19223314Snwhitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20223314Snwhitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21223314Snwhitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22223314Snwhitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23223314Snwhitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24223314Snwhitehorn * 25223314Snwhitehorn * $FreeBSD$ 26223314Snwhitehorn */ 27223314Snwhitehorn 28223314Snwhitehorn#include <sys/cdefs.h> 29223314Snwhitehorn__FBSDID("$FreeBSD$"); 30223314Snwhitehorn 31223314Snwhitehorn#include <sys/stdint.h> 32223314Snwhitehorn#include <sys/stddef.h> 33223314Snwhitehorn#include <sys/param.h> 34223314Snwhitehorn#include <sys/queue.h> 35223314Snwhitehorn#include <sys/types.h> 36223314Snwhitehorn#include <sys/systm.h> 37223314Snwhitehorn#include <sys/kernel.h> 38223314Snwhitehorn#include <sys/bus.h> 39223314Snwhitehorn#include <sys/linker_set.h> 40223314Snwhitehorn#include <sys/module.h> 41223314Snwhitehorn#include <sys/lock.h> 42223314Snwhitehorn#include <sys/mutex.h> 43223314Snwhitehorn#include <sys/condvar.h> 44223314Snwhitehorn#include <sys/sysctl.h> 45223314Snwhitehorn#include <sys/sx.h> 46223314Snwhitehorn#include <sys/unistd.h> 47223314Snwhitehorn#include <sys/callout.h> 48223314Snwhitehorn#include <sys/malloc.h> 49223314Snwhitehorn#include <sys/priv.h> 50223314Snwhitehorn 51223314Snwhitehorn#include <sys/rman.h> 52223314Snwhitehorn 53223314Snwhitehorn#include <dev/usb/usb.h> 54223314Snwhitehorn#include <dev/usb/usbdi.h> 55223314Snwhitehorn 56223314Snwhitehorn#include <dev/usb/usb_core.h> 57223314Snwhitehorn#include <dev/usb/usb_busdma.h> 58223314Snwhitehorn#include <dev/usb/usb_process.h> 59223314Snwhitehorn#include <dev/usb/usb_util.h> 60223314Snwhitehorn 61223314Snwhitehorn#include <dev/usb/usb_controller.h> 62223314Snwhitehorn#include <dev/usb/usb_bus.h> 63223314Snwhitehorn#include <dev/usb/controller/ohci.h> 64223314Snwhitehorn#include <dev/usb/controller/ohcireg.h> 65223314Snwhitehorn 66223314Snwhitehorn#include "ps3bus.h" 67223314Snwhitehorn 68223314Snwhitehornstatic int 69223314Snwhitehornohci_ps3_probe(device_t dev) 70223314Snwhitehorn{ 71223314Snwhitehorn if (ps3bus_get_bustype(dev) != PS3_BUSTYPE_SYSBUS || 72223314Snwhitehorn ps3bus_get_devtype(dev) != PS3_DEVTYPE_USB) 73223314Snwhitehorn return (ENXIO); 74223314Snwhitehorn 75223314Snwhitehorn device_set_desc(dev, "Playstation 3 USB 2.0 controller"); 76223314Snwhitehorn return (BUS_PROBE_SPECIFIC); 77223314Snwhitehorn} 78223314Snwhitehorn 79223314Snwhitehornstatic int 80223314Snwhitehornohci_ps3_attach(device_t dev) 81223314Snwhitehorn{ 82223314Snwhitehorn ohci_softc_t *sc = device_get_softc(dev); 83223314Snwhitehorn int rid, err; 84223314Snwhitehorn 85223314Snwhitehorn sc->sc_bus.parent = dev; 86223314Snwhitehorn sc->sc_bus.devices = sc->sc_devices; 87223314Snwhitehorn sc->sc_bus.devices_max = OHCI_MAX_DEVICES; 88223314Snwhitehorn 89223314Snwhitehorn if (usb_bus_mem_alloc_all(&sc->sc_bus, 90223314Snwhitehorn USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) 91223314Snwhitehorn return (ENOMEM); 92223314Snwhitehorn 93223314Snwhitehorn rid = 0; 94223314Snwhitehorn sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 95223314Snwhitehorn &rid, RF_ACTIVE); 96223314Snwhitehorn 97223314Snwhitehorn if (!sc->sc_io_res) { 98223314Snwhitehorn device_printf(dev, "Could not map memory\n"); 99223314Snwhitehorn goto error; 100223314Snwhitehorn } 101223314Snwhitehorn 102223314Snwhitehorn sc->sc_io_tag = rman_get_bustag(sc->sc_io_res); 103223314Snwhitehorn sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); 104223314Snwhitehorn sc->sc_io_size = rman_get_size(sc->sc_io_res); 105223314Snwhitehorn 106223314Snwhitehorn rid = 0; 107223314Snwhitehorn sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 108223314Snwhitehorn RF_SHAREABLE | RF_ACTIVE); 109223314Snwhitehorn 110223314Snwhitehorn if (sc->sc_irq_res == NULL) { 111223314Snwhitehorn device_printf(dev, "Could not allocate irq\n"); 112223314Snwhitehorn return (ENXIO); 113223314Snwhitehorn } 114223314Snwhitehorn 115223314Snwhitehorn sc->sc_bus.bdev = device_add_child(dev, "usbus", -1); 116223314Snwhitehorn if (!sc->sc_bus.bdev) { 117223314Snwhitehorn device_printf(dev, "Could not add USB device\n"); 118223314Snwhitehorn return (ENXIO); 119223314Snwhitehorn } 120223314Snwhitehorn 121223314Snwhitehorn device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); 122223314Snwhitehorn 123223314Snwhitehorn sprintf(sc->sc_vendor, "Sony"); 124223314Snwhitehorn 125223314Snwhitehorn err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 126223314Snwhitehorn NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_intr_hdl); 127223314Snwhitehorn if (err) { 128223314Snwhitehorn device_printf(dev, "Could not setup error irq, %d\n", err); 129223314Snwhitehorn goto error; 130223314Snwhitehorn } 131223314Snwhitehorn 132223314Snwhitehorn //sc->sc_flags |= EHCI_SCFLG_BIGEMMIO; 133223314Snwhitehorn bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, 134223314Snwhitehorn OHCI_CONTROL, 0); 135223314Snwhitehorn err = ohci_init(sc); 136223314Snwhitehorn if (err) { 137223314Snwhitehorn device_printf(dev, "USB init failed err=%d\n", err); 138223314Snwhitehorn goto error; 139223314Snwhitehorn } 140223314Snwhitehorn 141223314Snwhitehorn err = device_probe_and_attach(sc->sc_bus.bdev); 142223314Snwhitehorn if (err == 0) 143223314Snwhitehorn return (0); 144223314Snwhitehorn 145223314Snwhitehornerror: 146223314Snwhitehorn return (ENXIO); 147223314Snwhitehorn} 148223314Snwhitehorn 149223314Snwhitehornstatic device_method_t ohci_ps3_methods[] = { 150223314Snwhitehorn /* Device interface */ 151223314Snwhitehorn DEVMETHOD(device_probe, ohci_ps3_probe), 152223314Snwhitehorn DEVMETHOD(device_attach, ohci_ps3_attach), 153229096Shselasky DEVMETHOD(device_resume, bus_generic_resume), 154229096Shselasky DEVMETHOD(device_suspend, bus_generic_suspend), 155229096Shselasky DEVMETHOD(device_shutdown, bus_generic_shutdown), 156223314Snwhitehorn 157229093Shselasky DEVMETHOD_END 158223314Snwhitehorn}; 159223314Snwhitehorn 160223314Snwhitehornstatic driver_t ohci_ps3_driver = { 161229096Shselasky .name = "ohci", 162229096Shselasky .methods = ohci_ps3_methods, 163229096Shselasky .size = sizeof(ohci_softc_t), 164223314Snwhitehorn}; 165223314Snwhitehorn 166223314Snwhitehornstatic devclass_t ohci_ps3_devclass; 167223314Snwhitehorn 168223314SnwhitehornDRIVER_MODULE(ohci_ps3, ps3bus, ohci_ps3_driver, ohci_ps3_devclass, 0, 0); 169223314SnwhitehornMODULE_DEPEND(ohci_ps3, usb, 1, 1, 1); 170223314Snwhitehorn 171