ppbconf.c (184130) | ppbconf.c (185003) |
---|---|
1/*- 2 * Copyright (c) 1997, 1998, 1999 Nicolas Souchu 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 --- 13 unchanged lines hidden (view full) --- 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997, 1998, 1999 Nicolas Souchu 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 --- 13 unchanged lines hidden (view full) --- 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/dev/ppbus/ppbconf.c 184130 2008-10-21 18:30:10Z jhb $"); | 30__FBSDID("$FreeBSD: head/sys/dev/ppbus/ppbconf.c 185003 2008-11-16 17:42:02Z jhb $"); |
31#include "opt_ppb_1284.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/module.h> 37#include <sys/bus.h> 38#include <sys/malloc.h> 39#include <sys/rman.h> 40 41#include <machine/resource.h> 42 43#include <dev/ppbus/ppbconf.h> 44#include <dev/ppbus/ppb_1284.h> 45 46#include "ppbus_if.h" | 31#include "opt_ppb_1284.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/module.h> 37#include <sys/bus.h> 38#include <sys/malloc.h> 39#include <sys/rman.h> 40 41#include <machine/resource.h> 42 43#include <dev/ppbus/ppbconf.h> 44#include <dev/ppbus/ppb_1284.h> 45 46#include "ppbus_if.h" |
47 | 47 |
48#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev)) | 48#define DEVTOSOFTC(dev) ((struct ppb_data *)device_get_softc(dev)) |
49 | 49 |
50static MALLOC_DEFINE(M_PPBUSDEV, "ppbusdev", "Parallel Port bus device"); 51 52 53/* 54 * Device methods 55 */ 56 57static int --- 27 unchanged lines hidden (view full) --- 85 * 86 * Add a ppbus device, allocate/initialize the ivars 87 */ 88static device_t 89ppbus_add_child(device_t dev, int order, const char *name, int unit) 90{ 91 struct ppb_device *ppbdev; 92 device_t child; | 50static MALLOC_DEFINE(M_PPBUSDEV, "ppbusdev", "Parallel Port bus device"); 51 52 53/* 54 * Device methods 55 */ 56 57static int --- 27 unchanged lines hidden (view full) --- 85 * 86 * Add a ppbus device, allocate/initialize the ivars 87 */ 88static device_t 89ppbus_add_child(device_t dev, int order, const char *name, int unit) 90{ 91 struct ppb_device *ppbdev; 92 device_t child; |
93 | 93 |
94 /* allocate ivars for the new ppbus child */ 95 ppbdev = malloc(sizeof(struct ppb_device), M_PPBUSDEV, 96 M_NOWAIT | M_ZERO); 97 if (!ppbdev) | 94 /* allocate ivars for the new ppbus child */ 95 ppbdev = malloc(sizeof(struct ppb_device), M_PPBUSDEV, 96 M_NOWAIT | M_ZERO); 97 if (!ppbdev) |
98 return NULL; | 98 return (NULL); |
99 100 /* initialize the ivars */ 101 ppbdev->name = name; 102 103 /* add the device as a child to the ppbus bus with the allocated 104 * ivars */ 105 child = device_add_child_ordered(dev, order, name, unit); 106 device_set_ivars(child, ppbdev); 107 | 99 100 /* initialize the ivars */ 101 ppbdev->name = name; 102 103 /* add the device as a child to the ppbus bus with the allocated 104 * ivars */ 105 child = device_add_child_ordered(dev, order, name, unit); 106 device_set_ivars(child, ppbdev); 107 |
108 return child; | 108 return (child); |
109} 110 111static int 112ppbus_read_ivar(device_t bus, device_t dev, int index, uintptr_t* val) 113{ | 109} 110 111static int 112ppbus_read_ivar(device_t bus, device_t dev, int index, uintptr_t* val) 113{ |
114 | 114 |
115 switch (index) { 116 case PPBUS_IVAR_MODE: 117 /* XXX yet device mode = ppbus mode = chipset mode */ 118 *val = (u_long)ppb_get_mode(bus); 119 break; 120 default: 121 return (ENOENT); 122 } | 115 switch (index) { 116 case PPBUS_IVAR_MODE: 117 /* XXX yet device mode = ppbus mode = chipset mode */ 118 *val = (u_long)ppb_get_mode(bus); 119 break; 120 default: 121 return (ENOENT); 122 } |
123 | 123 |
124 return (0); 125} | 124 return (0); 125} |
126 | 126 |
127static int | 127static int |
128ppbus_write_ivar(device_t bus, device_t dev, int index, u_long val) | 128ppbus_write_ivar(device_t bus, device_t dev, int index, uintptr_t val) |
129{ 130 131 switch (index) { 132 case PPBUS_IVAR_MODE: 133 /* XXX yet device mode = ppbus mode = chipset mode */ 134 ppb_set_mode(bus, val); 135 break; 136 default: --- 66 unchanged lines hidden (view full) --- 203ppb_pnp_detect(device_t bus) 204{ 205 char *token, *class = 0; 206 int i, len, error; 207 int class_id = -1; 208 char str[PPB_PnP_STRING_SIZE+1]; 209 210 device_printf(bus, "Probing for PnP devices:\n"); | 129{ 130 131 switch (index) { 132 case PPBUS_IVAR_MODE: 133 /* XXX yet device mode = ppbus mode = chipset mode */ 134 ppb_set_mode(bus, val); 135 break; 136 default: --- 66 unchanged lines hidden (view full) --- 203ppb_pnp_detect(device_t bus) 204{ 205 char *token, *class = 0; 206 int i, len, error; 207 int class_id = -1; 208 char str[PPB_PnP_STRING_SIZE+1]; 209 210 device_printf(bus, "Probing for PnP devices:\n"); |
211 | 211 |
212 if ((error = ppb_1284_read_id(bus, PPB_NIBBLE, str, 213 PPB_PnP_STRING_SIZE, &len))) 214 goto end_detect; 215 216#ifdef DEBUG_1284 217 device_printf(bus, "<PnP> %d characters: ", len); 218 for (i = 0; i < len; i++) 219 printf("%c(0x%x) ", str[i], str[i]); --- 62 unchanged lines hidden (view full) --- 282 */ 283static int 284ppb_scan_bus(device_t bus) 285{ 286 struct ppb_data * ppb = (struct ppb_data *)device_get_softc(bus); 287 int error = 0; 288 289 /* try all IEEE1284 modes, for one device only | 212 if ((error = ppb_1284_read_id(bus, PPB_NIBBLE, str, 213 PPB_PnP_STRING_SIZE, &len))) 214 goto end_detect; 215 216#ifdef DEBUG_1284 217 device_printf(bus, "<PnP> %d characters: ", len); 218 for (i = 0; i < len; i++) 219 printf("%c(0x%x) ", str[i], str[i]); --- 62 unchanged lines hidden (view full) --- 282 */ 283static int 284ppb_scan_bus(device_t bus) 285{ 286 struct ppb_data * ppb = (struct ppb_data *)device_get_softc(bus); 287 int error = 0; 288 289 /* try all IEEE1284 modes, for one device only |
290 * | 290 * |
291 * XXX We should implement the IEEE1284.3 standard to detect 292 * daisy chained devices 293 */ 294 295 error = ppb_1284_negociate(bus, PPB_NIBBLE, PPB_REQUEST_ID); 296 297 if ((ppb->state == PPB_ERROR) && (ppb->error == PPB_NOT_IEEE1284)) 298 goto end_scan; --- 80 unchanged lines hidden (view full) --- 379 /* Locate our children */ 380 bus_generic_probe(dev); 381 382#ifndef DONTPROBE_1284 383 /* detect IEEE1284 compliant devices */ 384 ppb_scan_bus(dev); 385#endif /* !DONTPROBE_1284 */ 386 | 291 * XXX We should implement the IEEE1284.3 standard to detect 292 * daisy chained devices 293 */ 294 295 error = ppb_1284_negociate(bus, PPB_NIBBLE, PPB_REQUEST_ID); 296 297 if ((ppb->state == PPB_ERROR) && (ppb->error == PPB_NOT_IEEE1284)) 298 goto end_scan; --- 80 unchanged lines hidden (view full) --- 379 /* Locate our children */ 380 bus_generic_probe(dev); 381 382#ifndef DONTPROBE_1284 383 /* detect IEEE1284 compliant devices */ 384 ppb_scan_bus(dev); 385#endif /* !DONTPROBE_1284 */ 386 |
387 /* launch attachement of the added children */ | 387 /* launch attachment of the added children */ |
388 bus_generic_attach(dev); 389 390 return (0); 391} 392 393static int 394ppbus_detach(device_t dev) 395{ | 388 bus_generic_attach(dev); 389 390 return (0); 391} 392 393static int 394ppbus_detach(device_t dev) 395{ |
396 device_t *children; 397 int error, nchildren, i; | 396 device_t *children; 397 int error, nchildren, i; |
398 399 error = bus_generic_detach(dev); 400 if (error) 401 return (error); 402 403 /* detach & delete all children */ 404 if (!device_get_children(dev, &children, &nchildren)) { 405 for (i = 0; i < nchildren; i++) 406 if (children[i]) 407 device_delete_child(dev, children[i]); 408 free(children, M_TEMP); | 398 399 error = bus_generic_detach(dev); 400 if (error) 401 return (error); 402 403 /* detach & delete all children */ 404 if (!device_get_children(dev, &children, &nchildren)) { 405 for (i = 0; i < nchildren; i++) 406 if (children[i]) 407 device_delete_child(dev, children[i]); 408 free(children, M_TEMP); |
409 } | 409 } |
410 411 return (0); 412} 413 414static int 415ppbus_setup_intr(device_t bus, device_t child, struct resource *r, int flags, 416 driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep) 417{ --- 18 unchanged lines hidden (view full) --- 436 return (0); 437} 438 439static int 440ppbus_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih) 441{ 442 struct ppb_data *ppb = DEVTOSOFTC(bus); 443 struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(child); | 410 411 return (0); 412} 413 414static int 415ppbus_setup_intr(device_t bus, device_t child, struct resource *r, int flags, 416 driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep) 417{ --- 18 unchanged lines hidden (view full) --- 436 return (0); 437} 438 439static int 440ppbus_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih) 441{ 442 struct ppb_data *ppb = DEVTOSOFTC(bus); 443 struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(child); |
444 | 444 |
445 /* a device driver must own the bus to unregister an interrupt */ 446 if ((ppb->ppb_owner != child) || (ppbdev->intr_cookie != ih) || 447 (ppbdev->intr_resource != r)) 448 return (EINVAL); 449 450 ppbdev->intr_cookie = 0; 451 ppbdev->intr_resource = 0; 452 --- 11 unchanged lines hidden (view full) --- 464int 465ppb_request_bus(device_t bus, device_t dev, int how) 466{ 467 int s, error = 0; 468 struct ppb_data *ppb = DEVTOSOFTC(bus); 469 struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev); 470 471 while (!error) { | 445 /* a device driver must own the bus to unregister an interrupt */ 446 if ((ppb->ppb_owner != child) || (ppbdev->intr_cookie != ih) || 447 (ppbdev->intr_resource != r)) 448 return (EINVAL); 449 450 ppbdev->intr_cookie = 0; 451 ppbdev->intr_resource = 0; 452 --- 11 unchanged lines hidden (view full) --- 464int 465ppb_request_bus(device_t bus, device_t dev, int how) 466{ 467 int s, error = 0; 468 struct ppb_data *ppb = DEVTOSOFTC(bus); 469 struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev); 470 471 while (!error) { |
472 s = splhigh(); | 472 s = splhigh(); |
473 if (ppb->ppb_owner) { 474 splx(s); 475 476 switch (how) { 477 case (PPB_WAIT | PPB_INTR): 478 error = tsleep(ppb, PPBPRI|PCATCH, "ppbreq", 0); 479 break; 480 --- 7 unchanged lines hidden (view full) --- 488 } 489 490 } else { 491 ppb->ppb_owner = dev; 492 493 /* restore the context of the device 494 * The first time, ctx.valid is certainly false 495 * then do not change anything. This is usefull for | 473 if (ppb->ppb_owner) { 474 splx(s); 475 476 switch (how) { 477 case (PPB_WAIT | PPB_INTR): 478 error = tsleep(ppb, PPBPRI|PCATCH, "ppbreq", 0); 479 break; 480 --- 7 unchanged lines hidden (view full) --- 488 } 489 490 } else { 491 ppb->ppb_owner = dev; 492 493 /* restore the context of the device 494 * The first time, ctx.valid is certainly false 495 * then do not change anything. This is usefull for |
496 * drivers that do not set there operating mode | 496 * drivers that do not set there operating mode |
497 * during attachement 498 */ 499 if (ppbdev->ctx.valid) 500 ppb_set_mode(bus, ppbdev->ctx.mode); 501 502 splx(s); 503 return (0); 504 } --- 39 unchanged lines hidden (view full) --- 544 wakeup(ppb); 545 546 return (0); 547} 548 549static devclass_t ppbus_devclass; 550 551static device_method_t ppbus_methods[] = { | 497 * during attachement 498 */ 499 if (ppbdev->ctx.valid) 500 ppb_set_mode(bus, ppbdev->ctx.mode); 501 502 splx(s); 503 return (0); 504 } --- 39 unchanged lines hidden (view full) --- 544 wakeup(ppb); 545 546 return (0); 547} 548 549static devclass_t ppbus_devclass; 550 551static device_method_t ppbus_methods[] = { |
552 /* device interface */ 553 DEVMETHOD(device_probe, ppbus_probe), 554 DEVMETHOD(device_attach, ppbus_attach), 555 DEVMETHOD(device_detach, ppbus_detach), 556 557 /* bus interface */ | 552 /* device interface */ 553 DEVMETHOD(device_probe, ppbus_probe), 554 DEVMETHOD(device_attach, ppbus_attach), 555 DEVMETHOD(device_detach, ppbus_detach), 556 557 /* bus interface */ |
558 DEVMETHOD(bus_add_child, ppbus_add_child), 559 DEVMETHOD(bus_print_child, ppbus_print_child), | 558 DEVMETHOD(bus_add_child, ppbus_add_child), 559 DEVMETHOD(bus_print_child, ppbus_print_child), |
560 DEVMETHOD(bus_read_ivar, ppbus_read_ivar), 561 DEVMETHOD(bus_write_ivar, ppbus_write_ivar), | 560 DEVMETHOD(bus_read_ivar, ppbus_read_ivar), 561 DEVMETHOD(bus_write_ivar, ppbus_write_ivar), |
562 DEVMETHOD(bus_setup_intr, ppbus_setup_intr), 563 DEVMETHOD(bus_teardown_intr, ppbus_teardown_intr), 564 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), | 562 DEVMETHOD(bus_setup_intr, ppbus_setup_intr), 563 DEVMETHOD(bus_teardown_intr, ppbus_teardown_intr), 564 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), |
565 DEVMETHOD(bus_release_resource, bus_generic_release_resource), | 565 DEVMETHOD(bus_release_resource, bus_generic_release_resource), |
566 | 566 |
567 { 0, 0 } | 567 { 0, 0 } |
568}; 569 570static driver_t ppbus_driver = { | 568}; 569 570static driver_t ppbus_driver = { |
571 "ppbus", 572 ppbus_methods, 573 sizeof(struct ppb_data), | 571 "ppbus", 572 ppbus_methods, 573 sizeof(struct ppb_data), |
574}; 575DRIVER_MODULE(ppbus, ppc, ppbus_driver, ppbus_devclass, 0, 0); | 574}; 575DRIVER_MODULE(ppbus, ppc, ppbus_driver, ppbus_devclass, 0, 0); |