uhci_pci.c revision 184610
1/*- 2 * Copyright (c) 1998 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Lennart Augustsson (augustss@carlstedt.se) at 7 * Carlstedt Research & Technology. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the NetBSD 20 * Foundation, Inc. and its contributors. 21 * 4. Neither the name of The NetBSD Foundation nor the names of its 22 * contributors may be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38#include <sys/cdefs.h> 39__FBSDID("$FreeBSD: head/sys/dev/usb2/controller/uhci2_pci.c 184610 2008-11-04 02:31:03Z alfred $"); 40 41/* Universal Host Controller Interface 42 * 43 * UHCI spec: http://www.intel.com/ 44 */ 45 46/* The low level controller code for UHCI has been split into 47 * PCI probes and UHCI specific code. This was done to facilitate the 48 * sharing of code between *BSD's 49 */ 50 51#include <dev/usb2/include/usb2_mfunc.h> 52#include <dev/usb2/include/usb2_defs.h> 53#include <dev/usb2/include/usb2_standard.h> 54 55#include <dev/usb2/core/usb2_core.h> 56#include <dev/usb2/core/usb2_busdma.h> 57#include <dev/usb2/core/usb2_process.h> 58#include <dev/usb2/core/usb2_config_td.h> 59#include <dev/usb2/core/usb2_sw_transfer.h> 60#include <dev/usb2/core/usb2_util.h> 61#include <dev/usb2/core/usb2_debug.h> 62 63#include <dev/usb2/controller/usb2_controller.h> 64#include <dev/usb2/controller/usb2_bus.h> 65#include <dev/usb2/controller/usb2_pci.h> 66#include <dev/usb2/controller/uhci2.h> 67 68#define PCI_UHCI_VENDORID_INTEL 0x8086 69#define PCI_UHCI_VENDORID_VIA 0x1106 70 71/* PIIX4E has no separate stepping */ 72 73#define PCI_UHCI_BASE_REG 0x20 74 75static device_probe_t uhci_pci_probe; 76static device_attach_t uhci_pci_attach; 77static device_detach_t uhci_pci_detach; 78static device_suspend_t uhci_pci_suspend; 79static device_resume_t uhci_pci_resume; 80 81static int 82uhci_pci_suspend(device_t self) 83{ 84 uhci_softc_t *sc = device_get_softc(self); 85 int err; 86 87 err = bus_generic_suspend(self); 88 if (err) { 89 return (err); 90 } 91 uhci_suspend(sc); 92 return (0); 93} 94 95static int 96uhci_pci_resume(device_t self) 97{ 98 uhci_softc_t *sc = device_get_softc(self); 99 100 pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2); 101 102 uhci_resume(sc); 103 104 bus_generic_resume(self); 105 return (0); 106} 107 108static const char * 109uhci_pci_match(device_t self) 110{ 111 uint32_t device_id = pci_get_devid(self); 112 113 switch (device_id) { 114 case 0x26888086: 115 return ("Intel 631XESB/632XESB/3100 USB controller USB-1"); 116 117 case 0x26898086: 118 return ("Intel 631XESB/632XESB/3100 USB controller USB-2"); 119 120 case 0x268a8086: 121 return ("Intel 631XESB/632XESB/3100 USB controller USB-3"); 122 123 case 0x268b8086: 124 return ("Intel 631XESB/632XESB/3100 USB controller USB-4"); 125 126 case 0x70208086: 127 return ("Intel 82371SB (PIIX3) USB controller"); 128 129 case 0x71128086: 130 return ("Intel 82371AB/EB (PIIX4) USB controller"); 131 132 case 0x24128086: 133 return ("Intel 82801AA (ICH) USB controller"); 134 135 case 0x24228086: 136 return ("Intel 82801AB (ICH0) USB controller"); 137 138 case 0x24428086: 139 return ("Intel 82801BA/BAM (ICH2) USB controller USB-A"); 140 141 case 0x24448086: 142 return ("Intel 82801BA/BAM (ICH2) USB controller USB-B"); 143 144 case 0x24828086: 145 return ("Intel 82801CA/CAM (ICH3) USB controller USB-A"); 146 147 case 0x24848086: 148 return ("Intel 82801CA/CAM (ICH3) USB controller USB-B"); 149 150 case 0x24878086: 151 return ("Intel 82801CA/CAM (ICH3) USB controller USB-C"); 152 153 case 0x24c28086: 154 return ("Intel 82801DB (ICH4) USB controller USB-A"); 155 156 case 0x24c48086: 157 return ("Intel 82801DB (ICH4) USB controller USB-B"); 158 159 case 0x24c78086: 160 return ("Intel 82801DB (ICH4) USB controller USB-C"); 161 162 case 0x24d28086: 163 return ("Intel 82801EB (ICH5) USB controller USB-A"); 164 165 case 0x24d48086: 166 return ("Intel 82801EB (ICH5) USB controller USB-B"); 167 168 case 0x24d78086: 169 return ("Intel 82801EB (ICH5) USB controller USB-C"); 170 171 case 0x24de8086: 172 return ("Intel 82801EB (ICH5) USB controller USB-D"); 173 174 case 0x26588086: 175 return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-A"); 176 177 case 0x26598086: 178 return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-B"); 179 180 case 0x265a8086: 181 return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-C"); 182 183 case 0x265b8086: 184 return ("Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-D"); 185 186 case 0x28308086: 187 return ("Intel 82801H (ICH8) USB controller USB-A"); 188 case 0x28318086: 189 return ("Intel 82801H (ICH8) USB controller USB-B"); 190 case 0x28328086: 191 return ("Intel 82801H (ICH8) USB controller USB-C"); 192 case 0x28348086: 193 return ("Intel 82801H (ICH8) USB controller USB-D"); 194 case 0x28358086: 195 return ("Intel 82801H (ICH8) USB controller USB-E"); 196 case 0x29348086: 197 return ("Intel 82801I (ICH9) USB controller"); 198 case 0x29358086: 199 return ("Intel 82801I (ICH9) USB controller"); 200 case 0x29368086: 201 return ("Intel 82801I (ICH9) USB controller"); 202 case 0x29378086: 203 return ("Intel 82801I (ICH9) USB controller"); 204 case 0x29388086: 205 return ("Intel 82801I (ICH9) USB controller"); 206 case 0x29398086: 207 return ("Intel 82801I (ICH9) USB controller"); 208 209 case 0x719a8086: 210 return ("Intel 82443MX USB controller"); 211 212 case 0x76028086: 213 return ("Intel 82372FB/82468GX USB controller"); 214 215 case 0x30381106: 216 return ("VIA 83C572 USB controller"); 217 218 default: 219 break; 220 } 221 222 if ((pci_get_class(self) == PCIC_SERIALBUS) && 223 (pci_get_subclass(self) == PCIS_SERIALBUS_USB) && 224 (pci_get_progif(self) == PCI_INTERFACE_UHCI)) { 225 return ("UHCI (generic) USB controller"); 226 } 227 return (NULL); 228} 229 230static int 231uhci_pci_probe(device_t self) 232{ 233 const char *desc = uhci_pci_match(self); 234 235 if (desc) { 236 device_set_desc(self, desc); 237 return (0); 238 } else { 239 return (ENXIO); 240 } 241} 242 243static int 244uhci_pci_attach(device_t self) 245{ 246 uhci_softc_t *sc = device_get_softc(self); 247 int rid; 248 int err; 249 250 if (sc == NULL) { 251 device_printf(self, "Could not allocate sc\n"); 252 return (ENXIO); 253 } 254 /* get all DMA memory */ 255 256 if (usb2_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self), 257 &uhci_iterate_hw_softc)) { 258 return ENOMEM; 259 } 260 sc->sc_dev = self; 261 262 pci_enable_busmaster(self); 263 264 rid = PCI_UHCI_BASE_REG; 265 sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_IOPORT, &rid, 266 RF_ACTIVE); 267 if (!sc->sc_io_res) { 268 device_printf(self, "Could not map ports\n"); 269 goto error; 270 } 271 sc->sc_io_tag = rman_get_bustag(sc->sc_io_res); 272 sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); 273 sc->sc_io_size = rman_get_size(sc->sc_io_res); 274 275 /* disable interrupts */ 276 bus_space_write_2(sc->sc_io_tag, sc->sc_io_hdl, UHCI_INTR, 0); 277 278 rid = 0; 279 sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, 280 RF_SHAREABLE | RF_ACTIVE); 281 if (sc->sc_irq_res == NULL) { 282 device_printf(self, "Could not allocate irq\n"); 283 goto error; 284 } 285 sc->sc_bus.bdev = device_add_child(self, "usbus", -1); 286 if (!sc->sc_bus.bdev) { 287 device_printf(self, "Could not add USB device\n"); 288 goto error; 289 } 290 device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); 291 292 /* 293 * uhci_pci_match must never return NULL if uhci_pci_probe 294 * succeeded 295 */ 296 device_set_desc(sc->sc_bus.bdev, uhci_pci_match(self)); 297 switch (pci_get_vendor(self)) { 298 case PCI_UHCI_VENDORID_INTEL: 299 sprintf(sc->sc_vendor, "Intel"); 300 break; 301 case PCI_UHCI_VENDORID_VIA: 302 sprintf(sc->sc_vendor, "VIA"); 303 break; 304 default: 305 if (bootverbose) { 306 device_printf(self, "(New UHCI DeviceId=0x%08x)\n", 307 pci_get_devid(self)); 308 } 309 sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self)); 310 } 311 312 switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USB_REV_MASK) { 313 case PCI_USB_REV_PRE_1_0: 314 sc->sc_bus.usbrev = USB_REV_PRE_1_0; 315 break; 316 case PCI_USB_REV_1_0: 317 sc->sc_bus.usbrev = USB_REV_1_0; 318 break; 319 default: 320 sc->sc_bus.usbrev = USB_REV_UNKNOWN; 321 break; 322 } 323 324 err = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_bus.mtx, 325 NULL, 0, 4); 326 if (err) { 327 device_printf(self, "could not setup config thread!\n"); 328 goto error; 329 } 330#if (__FreeBSD_version >= 700031) 331 err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 332 NULL, (void *)(void *)uhci_interrupt, sc, &sc->sc_intr_hdl); 333#else 334 err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, 335 (void *)(void *)uhci_interrupt, sc, &sc->sc_intr_hdl); 336#endif 337 338 if (err) { 339 device_printf(self, "Could not setup irq, %d\n", err); 340 sc->sc_intr_hdl = NULL; 341 goto error; 342 } 343 /* 344 * Set the PIRQD enable bit and switch off all the others. We don't 345 * want legacy support to interfere with us XXX Does this also mean 346 * that the BIOS won't touch the keyboard anymore if it is connected 347 * to the ports of the root hub? 348 */ 349#if USB_DEBUG 350 if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN) { 351 device_printf(self, "LegSup = 0x%04x\n", 352 pci_read_config(self, PCI_LEGSUP, 2)); 353 } 354#endif 355 pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2); 356 357 err = uhci_init(sc); 358 if (!err) { 359 err = device_probe_and_attach(sc->sc_bus.bdev); 360 } 361 if (err) { 362 device_printf(self, "USB init failed\n"); 363 goto error; 364 } 365 return (0); 366 367error: 368 uhci_pci_detach(self); 369 return (ENXIO); 370} 371 372int 373uhci_pci_detach(device_t self) 374{ 375 uhci_softc_t *sc = device_get_softc(self); 376 device_t bdev; 377 378 usb2_config_td_drain(&sc->sc_config_td); 379 380 if (sc->sc_bus.bdev) { 381 bdev = sc->sc_bus.bdev; 382 device_detach(bdev); 383 device_delete_child(self, bdev); 384 } 385 /* during module unload there are lots of children leftover */ 386 device_delete_all_children(self); 387 388 /* 389 * disable interrupts that might have been switched on in 390 * uhci_init. 391 */ 392 if (sc->sc_io_res) { 393 mtx_lock(&sc->sc_bus.mtx); 394 395 /* stop the controller */ 396 uhci_reset(sc); 397 398 mtx_unlock(&sc->sc_bus.mtx); 399 } 400 pci_disable_busmaster(self); 401 402 if (sc->sc_irq_res && sc->sc_intr_hdl) { 403 int err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); 404 405 if (err) { 406 /* XXX or should we panic? */ 407 device_printf(self, "Could not tear down irq, %d\n", 408 err); 409 } 410 sc->sc_intr_hdl = NULL; 411 } 412 if (sc->sc_irq_res) { 413 bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res); 414 sc->sc_irq_res = NULL; 415 } 416 if (sc->sc_io_res) { 417 bus_release_resource(self, SYS_RES_IOPORT, PCI_UHCI_BASE_REG, 418 sc->sc_io_res); 419 sc->sc_io_res = NULL; 420 } 421 usb2_config_td_unsetup(&sc->sc_config_td); 422 423 usb2_bus_mem_free_all(&sc->sc_bus, &uhci_iterate_hw_softc); 424 425 return (0); 426} 427 428static driver_t uhci_driver = 429{ 430 .name = "uhci", 431 .methods = (device_method_t[]){ 432 /* device interface */ 433 DEVMETHOD(device_probe, uhci_pci_probe), 434 DEVMETHOD(device_attach, uhci_pci_attach), 435 DEVMETHOD(device_detach, uhci_pci_detach), 436 437 DEVMETHOD(device_suspend, uhci_pci_suspend), 438 DEVMETHOD(device_resume, uhci_pci_resume), 439 DEVMETHOD(device_shutdown, bus_generic_shutdown), 440 441 /* Bus interface */ 442 DEVMETHOD(bus_print_child, bus_generic_print_child), 443 {0, 0} 444 }, 445 .size = sizeof(struct uhci_softc), 446}; 447 448static devclass_t uhci_devclass; 449 450DRIVER_MODULE(uhci, pci, uhci_driver, uhci_devclass, 0, 0); 451DRIVER_MODULE(uhci, cardbus, uhci_driver, uhci_devclass, 0, 0); 452MODULE_DEPEND(uhci, usb2_controller, 1, 1, 1); 453MODULE_DEPEND(uhci, usb2_core, 1, 1, 1); 454