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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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 * $Id: ppbconf.c,v 1.9 1998/12/07 21:58:16 archie Exp $ 27 * 28 */ 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/kernel.h> 32 #include <sys/malloc.h> 33 34 #include <vm/vm.h> 35 #include <vm/pmap.h> 36 37 #include <dev/ppbus/ppbconf.h> 38 #include <dev/ppbus/ppb_1284.h> 39 40 #include "opt_ppb_1284.h" 41 42 LIST_HEAD(, ppb_data) ppbdata; /* list of existing ppbus */ 43 44 /* 45 * Add a null driver so that the linker set always exists. 46 */ 47 48 static struct ppb_driver nulldriver = { 49 NULL, NULL, "null" 50 }; 51 DATA_SET(ppbdriver_set, nulldriver); 52 53 54 /* 55 * ppb_alloc_bus() 56 * 57 * Allocate area to store the ppbus description. 58 */ 59 struct ppb_data * 60 ppb_alloc_bus(void) 61 { 62 struct ppb_data *ppb; 63 static int ppbdata_initted = 0; /* done-init flag */ 64 65 ppb = (struct ppb_data *) malloc(sizeof(struct ppb_data), 66 M_TEMP, M_NOWAIT); 67 68 /* 69 * Add the new parallel port bus to the list of existing ppbus. 70 */ 71 if (ppb) { 72 bzero(ppb, sizeof(struct ppb_data)); 73 74 if (!ppbdata_initted) { /* list not initialised */ 75 LIST_INIT(&ppbdata); 76 ppbdata_initted = 1; 77 } 78 LIST_INSERT_HEAD(&ppbdata, ppb, ppb_chain); 79 } else { 80 printf("ppb_alloc_bus: cannot malloc!\n"); 81 } 82 return(ppb); 83 } 84 85 #define PPB_PNP_PRINTER 0 86 #define PPB_PNP_MODEM 1 87 #define PPB_PNP_NET 2 88 #define PPB_PNP_HDC 3 89 #define PPB_PNP_PCMCIA 4 90 #define PPB_PNP_MEDIA 5 91 #define PPB_PNP_FDC 6 92 #define PPB_PNP_PORTS 7 93 #define PPB_PNP_SCANNER 8 94 #define PPB_PNP_DIGICAM 9 95 96 #ifndef DONTPROBE_1284 97 98 static char *pnp_tokens[] = { 99 "PRINTER", "MODEM", "NET", "HDC", "PCMCIA", "MEDIA", 100 "FDC", "PORTS", "SCANNER", "DIGICAM", "", NULL }; 101 102 #if 0 103 static char *pnp_classes[] = { 104 "printer", "modem", "network device", 105 "hard disk", "PCMCIA", "multimedia device", 106 "floppy disk", "ports", "scanner", 107 "digital camera", "unknown device", NULL }; 108 #endif 109 110 /* 111 * search_token() 112 * 113 * Search the first occurence of a token within a string 114 * 115 * XXX should use strxxx() calls 116 */ 117 static char * 118 search_token(char *str, int slen, char *token) 119 { 120 char *p; 121 int tlen, i, j; 122 123 #define UNKNOWN_LENGTH -1 124 125 if (slen == UNKNOWN_LENGTH) 126 /* get string's length */ 127 for (slen = 0, p = str; *p != '\0'; p++) 128 slen ++; 129 130 /* get token's length */ 131 for (tlen = 0, p = token; *p != '\0'; p++) 132 tlen ++; 133 134 if (tlen == 0) 135 return (str); 136 137 for (i = 0; i <= slen-tlen; i++) { 138 for (j = 0; j < tlen; j++) 139 if (str[i+j] != token[j]) 140 break; 141 if (j == tlen) 142 return (&str[i]); 143 } 144 145 return (NULL); 146 } 147 148 /* 149 * ppb_pnp_detect() 150 * 151 * Returns the class id. of the peripherial, -1 otherwise 152 */ 153 static int 154 ppb_pnp_detect(struct ppb_data *ppb, struct ppb_device *pnpdev) 155 { 156 char *token, *class = 0; 157 int i, len, error; 158 int class_id = -1; 159 char str[PPB_PnP_STRING_SIZE+1]; 160 161 printf("Probing for PnP devices on ppbus%d:\n", 162 ppb->ppb_link->adapter_unit); 163 164 if ((error = ppb_1284_read_id(pnpdev, PPB_NIBBLE, str, 165 PPB_PnP_STRING_SIZE, &len))) 166 goto end_detect; 167 168 #ifdef DEBUG_1284 169 printf("ppb: <PnP> %d characters: ", len); 170 for (i = 0; i < len; i++) 171 printf("%c(0x%x) ", str[i], str[i]); 172 printf("\n"); 173 #endif 174 175 /* replace ';' characters by '\0' */ 176 for (i = 0; i < len; i++) 177 str[i] = (str[i] == ';') ? '\0' : str[i]; 178 179 if ((token = search_token(str, len, "MFG")) != NULL || 180 (token = search_token(str, len, "MANUFACTURER")) != NULL) 181 printf("ppbus%d: <%s", ppb->ppb_link->adapter_unit, 182 search_token(token, UNKNOWN_LENGTH, ":") + 1); 183 else 184 printf("ppbus%d: <unknown", ppb->ppb_link->adapter_unit); 185 186 if ((token = search_token(str, len, "MDL")) != NULL || 187 (token = search_token(str, len, "MODEL")) != NULL) 188 printf(" %s", 189 search_token(token, UNKNOWN_LENGTH, ":") + 1); 190 else 191 printf(" unknown"); 192 193 if ((token = search_token(str, len, "VER")) != NULL) 194 printf("/%s", 195 search_token(token, UNKNOWN_LENGTH, ":") + 1); 196 197 if ((token = search_token(str, len, "REV")) != NULL) 198 printf(".%s", 199 search_token(token, UNKNOWN_LENGTH, ":") + 1); 200 201 printf(">"); 202 203 if ((token = search_token(str, len, "CLS")) != NULL) { 204 class = search_token(token, UNKNOWN_LENGTH, ":") + 1; 205 printf(" %s", class); 206 } 207 208 if ((token = search_token(str, len, "CMD")) != NULL || 209 (token = search_token(str, len, "COMMAND")) != NULL) 210 printf(" %s", 211 search_token(token, UNKNOWN_LENGTH, ":") + 1); 212 213 printf("\n"); 214 215 if (class) 216 /* identify class ident */ 217 for (i = 0; pnp_tokens[i] != NULL; i++) { 218 if (search_token(class, len, pnp_tokens[i]) != NULL) { 219 class_id = i; 220 goto end_detect; 221 } 222 } 223 224 class_id = PPB_PnP_UNKNOWN; 225 226 end_detect: 227 return (class_id); 228 } 229 230 /* 231 * ppb_scan_bus() 232 * 233 * Scan the ppbus for IEEE1284 compliant devices 234 */ 235 static int 236 ppb_scan_bus(struct ppb_data *ppb) 237 { 238 struct ppb_device pnpdev; /* temporary device to perform I/O */ 239 int error = 0; 240 241 /* initialize the pnpdev structure for future use */ 242 bzero(&pnpdev, sizeof(pnpdev)); 243 pnpdev.ppb = ppb; 244 245 if ((error = ppb_request_bus(&pnpdev, PPB_DONTWAIT))) { 246 if (bootverbose) 247 printf("ppb: cannot allocate ppbus!\n"); 248 249 return (error); 250 } 251 252 /* try all IEEE1284 modes, for one device only 253 * 254 * XXX We should implement the IEEE1284.3 standard to detect 255 * daisy chained devices 256 */ 257 258 error = ppb_1284_negociate(&pnpdev, PPB_NIBBLE, PPB_REQUEST_ID); 259 260 if ((ppb->state == PPB_ERROR) && (ppb->error == PPB_NOT_IEEE1284)) 261 goto end_scan; 262 263 ppb_1284_terminate(&pnpdev); 264 265 printf("ppc%d: IEEE1284 device found ", ppb->ppb_link->adapter_unit); 266 267 if (!(error = ppb_1284_negociate(&pnpdev, PPB_NIBBLE, 0))) { 268 printf("/NIBBLE"); 269 ppb_1284_terminate(&pnpdev); 270 } 271 272 if (!(error = ppb_1284_negociate(&pnpdev, PPB_PS2, 0))) { 273 printf("/PS2"); 274 ppb_1284_terminate(&pnpdev); 275 } 276 277 if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP, 0))) { 278 printf("/ECP"); 279 ppb_1284_terminate(&pnpdev); 280 } 281 282 if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP, PPB_USE_RLE))) { 283 printf("/ECP_RLE"); 284 ppb_1284_terminate(&pnpdev); 285 } 286 287 if (!(error = ppb_1284_negociate(&pnpdev, PPB_EPP, 0))) { 288 printf("/EPP"); 289 ppb_1284_terminate(&pnpdev); 290 } 291 292 #if 0 293 if (!(error = ppb_1284_negociate(&pnpdev, PPB_NIBBLE, PPB_REQUEST_ID))) { 294 printf("/NIBBLE_ID"); 295 ppb_1284_terminate(&pnpdev); 296 } 297 298 if (!(error = ppb_1284_negociate(&pnpdev, PPB_PS2, PPB_REQUEST_ID))) { 299 printf("/PS2_ID"); 300 ppb_1284_terminate(&pnpdev); 301 } 302 303 if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP, PPB_REQUEST_ID))) { 304 printf("/ECP_ID"); 305 ppb_1284_terminate(&pnpdev); 306 } 307 308 if (!(error = ppb_1284_negociate(&pnpdev, PPB_ECP, 309 PPB_REQUEST_ID | PPB_USE_RLE))) { 310 printf("/ECP_RLE_ID"); 311 ppb_1284_terminate(&pnpdev); 312 } 313 #endif 314 315 if (!(error = ppb_1284_negociate(&pnpdev, PPB_COMPATIBLE, 316 PPB_EXTENSIBILITY_LINK))) { 317 printf("/Extensibility Link"); 318 ppb_1284_terminate(&pnpdev); 319 } 320 321 printf(" in FORWARD_IDLE state\n"); 322 323 /* detect PnP devices */ 324 ppb->class_id = ppb_pnp_detect(ppb, &pnpdev); 325 326 ppb_release_bus(&pnpdev); 327 328 return (0); 329 330 end_scan: 331 ppb_release_bus(&pnpdev); 332 return (error); 333 } 334 335 #endif /* !DONTPROBE_1284 */ 336 337 /* 338 * ppb_attachdevs() 339 * 340 * Called by ppcattach(), this function probes the ppbus and 341 * attaches found devices. 342 */ 343 int 344 ppb_attachdevs(struct ppb_data *ppb) 345 { 346 struct ppb_device *dev; 347 struct ppb_driver **p_drvpp, *p_drvp; 348 349 LIST_INIT(&ppb->ppb_devs); /* initialise device/driver list */ 350 p_drvpp = (struct ppb_driver **)ppbdriver_set.ls_items; 351 352 #ifndef DONTPROBE_1284 353 /* detect IEEE1284 compliant devices */ 354 ppb_scan_bus(ppb); 355 #endif /* !DONTPROBE_1284 */ 356 357 /* 358 * Blindly try all probes here. Later we should look at 359 * the parallel-port PnP standard, and intelligently seek 360 * drivers based on configuration first. 361 */ 362 while ((p_drvp = *p_drvpp++) != NULL) { 363 if (p_drvp->probe && (dev = (p_drvp->probe(ppb))) != NULL) { 364 /* 365 * Add the device to the list of probed devices. 366 */ 367 LIST_INSERT_HEAD(&ppb->ppb_devs, dev, chain); 368 369 /* Call the device's attach routine */ 370 (void)p_drvp->attach(dev); 371 } 372 } 373 return (0); 374 } 375 376 /* 377 * ppb_next_bus() 378 * 379 * Return the next bus in ppbus queue 380 */ 381 struct ppb_data * 382 ppb_next_bus(struct ppb_data *ppb) 383 { 384 385 if (ppb == NULL) 386 return (ppbdata.lh_first); 387 388 return (ppb->ppb_chain.le_next); 389 } 390 391 /* 392 * ppb_lookup_bus() 393 * 394 * Get ppb_data structure pointer according to the base address of the ppbus 395 */ 396 struct ppb_data * 397 ppb_lookup_bus(int base_port) 398 { 399 struct ppb_data *ppb; 400 401 for (ppb = ppbdata.lh_first; ppb; ppb = ppb->ppb_chain.le_next) 402 if (ppb->ppb_link->base == base_port) 403 break; 404 405 return (ppb); 406 } 407 408 /* 409 * ppb_lookup_link() 410 * 411 * Get ppb_data structure pointer according to the unit value 412 * of the corresponding link structure 413 */ 414 struct ppb_data * 415 ppb_lookup_link(int unit) 416 { 417 struct ppb_data *ppb; 418 419 for (ppb = ppbdata.lh_first; ppb; ppb = ppb->ppb_chain.le_next) 420 if (ppb->ppb_link->adapter_unit == unit) 421 break; 422 423 return (ppb); 424 } 425 426 /* 427 * ppb_attach_device() 428 * 429 * Called by loadable kernel modules to add a device 430 */ 431 int 432 ppb_attach_device(struct ppb_device *dev) 433 { 434 struct ppb_data *ppb = dev->ppb; 435 436 /* add the device to the list of probed devices */ 437 LIST_INSERT_HEAD(&ppb->ppb_devs, dev, chain); 438 439 return (0); 440 } 441 442 /* 443 * ppb_remove_device() 444 * 445 * Called by loadable kernel modules to remove a device 446 */ 447 void 448 ppb_remove_device(struct ppb_device *dev) 449 { 450 451 /* remove the device from the list of probed devices */ 452 LIST_REMOVE(dev, chain); 453 454 return; 455 } 456 457 /* 458 * ppb_request_bus() 459 * 460 * Allocate the device to perform transfers. 461 * 462 * how : PPB_WAIT or PPB_DONTWAIT 463 */ 464 int 465 ppb_request_bus(struct ppb_device *dev, int how) 466 { 467 int s, error = 0; 468 struct ppb_data *ppb = dev->ppb; 469 470 while (!error) { 471 s = splhigh(); 472 if (ppb->ppb_owner) { 473 splx(s); 474 475 switch (how) { 476 case (PPB_WAIT | PPB_INTR): 477 error = tsleep(ppb, PPBPRI|PCATCH, "ppbreq", 0); 478 break; 479 480 case (PPB_WAIT | PPB_NOINTR): 481 error = tsleep(ppb, PPBPRI, "ppbreq", 0); 482 break; 483 484 default: 485 return (EWOULDBLOCK); 486 break; 487 } 488 489 } else { 490 ppb->ppb_owner = dev; 491 492 /* restore the context of the device 493 * The first time, ctx.valid is certainly false 494 * then do not change anything. This is usefull for 495 * drivers that do not set there operating mode 496 * during attachement 497 */ 498 if (dev->ctx.valid) 499 ppb_set_mode(dev, dev->ctx.mode); 500 501 splx(s); 502 return (0); 503 } 504 } 505 506 return (error); 507 } 508 509 /* 510 * ppb_release_bus() 511 * 512 * Release the device allocated with ppb_request_dev() 513 */ 514 int 515 ppb_release_bus(struct ppb_device *dev) 516 { 517 int s; 518 struct ppb_data *ppb = dev->ppb; 519 520 s = splhigh(); 521 if (ppb->ppb_owner != dev) { 522 splx(s); 523 return (EACCES); 524 } 525 526 ppb->ppb_owner = 0; 527 splx(s); 528 529 /* save the context of the device */ 530 dev->ctx.mode = ppb_get_mode(dev); 531 532 /* ok, now the context of the device is valid */ 533 dev->ctx.valid = 1; 534 535 /* wakeup waiting processes */ 536 wakeup(ppb); 537 538 return (0); 539 } 540