ppbconf.c (f1d19042b082d95f07a0027e596ba2405aa8a9a5) | ppbconf.c (bc35c17446fab005a7e11b67b9004736f1c8498b) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 1997, 1998 Nicolas Souchu | 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 --- 7 unchanged lines hidden (view full) --- 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 * | 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 --- 7 unchanged lines hidden (view full) --- 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.8 1998/09/20 14:41:54 nsouch Exp $ | 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 | 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 |
|
40LIST_HEAD(, ppb_data) ppbdata; /* list of existing ppbus */ 41 42/* 43 * Add a null driver so that the linker set always exists. 44 */ 45 46static struct ppb_driver nulldriver = { 47 NULL, NULL, "null" --- 27 unchanged lines hidden (view full) --- 75 } 76 LIST_INSERT_HEAD(&ppbdata, ppb, ppb_chain); 77 } else { 78 printf("ppb_alloc_bus: cannot malloc!\n"); 79 } 80 return(ppb); 81} 82 | 42LIST_HEAD(, ppb_data) ppbdata; /* list of existing ppbus */ 43 44/* 45 * Add a null driver so that the linker set always exists. 46 */ 47 48static struct ppb_driver nulldriver = { 49 NULL, NULL, "null" --- 27 unchanged lines hidden (view full) --- 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 |
|
83static char *pnp_tokens[] = { 84 "PRINTER", "MODEM", "NET", "HDC", "PCMCIA", "MEDIA", 85 "FDC", "PORTS", "SCANNER", "DIGICAM", "", NULL }; 86 | 98static char *pnp_tokens[] = { 99 "PRINTER", "MODEM", "NET", "HDC", "PCMCIA", "MEDIA", 100 "FDC", "PORTS", "SCANNER", "DIGICAM", "", NULL }; 101 |
102#if 0 |
|
87static char *pnp_classes[] = { 88 "printer", "modem", "network device", 89 "hard disk", "PCMCIA", "multimedia device", 90 "floppy disk", "ports", "scanner", 91 "digital camera", "unknown device", NULL }; | 103static 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 |
|
92 93/* 94 * search_token() 95 * 96 * Search the first occurence of a token within a string 97 * 98 * XXX should use strxxx() calls 99 */ --- 29 unchanged lines hidden (view full) --- 129} 130 131/* 132 * ppb_pnp_detect() 133 * 134 * Returns the class id. of the peripherial, -1 otherwise 135 */ 136static int | 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 */ --- 29 unchanged lines hidden (view full) --- 146} 147 148/* 149 * ppb_pnp_detect() 150 * 151 * Returns the class id. of the peripherial, -1 otherwise 152 */ 153static int |
137ppb_pnp_detect(struct ppb_data *ppb) | 154ppb_pnp_detect(struct ppb_data *ppb, struct ppb_device *pnpdev) |
138{ | 155{ |
139 char *token, *q, *class = 0; | 156 char *token, *class = 0; |
140 int i, len, error; 141 int class_id = -1; 142 char str[PPB_PnP_STRING_SIZE+1]; | 157 int i, len, error; 158 int class_id = -1; 159 char str[PPB_PnP_STRING_SIZE+1]; |
143 struct ppb_device pnpdev; /* temporary device to perform I/O */ | |
144 | 160 |
145 /* initialize the pnpdev structure for future use */ 146 bzero(&pnpdev, sizeof(pnpdev)); 147 148 pnpdev.ppb = ppb; 149 150 if (bootverbose) 151 printf("ppb: <PnP> probing devices on ppbus %d...\n", | 161 printf("Probing for PnP devices on ppbus%d:\n", |
152 ppb->ppb_link->adapter_unit); | 162 ppb->ppb_link->adapter_unit); |
153 154 if (ppb_request_bus(&pnpdev, PPB_DONTWAIT)) { 155 if (bootverbose) 156 printf("ppb: <PnP> cannot allocate ppbus!\n"); 157 return (-1); 158 } 159 160 if ((error = ppb_1284_negociate(&pnpdev, NIBBLE_1284_REQUEST_ID))) { 161 if (bootverbose) 162 printf("ppb: <PnP> ppb_1284_negociate()=%d\n", error); 163 164 goto end_detect; 165 } | |
166 | 163 |
167 len = 0; 168 for (q=str; !(ppb_rstr(&pnpdev) & PERROR); q++) { 169 if ((error = nibble_1284_inbyte(&pnpdev, q))) { 170 if (bootverbose) { 171 *q = '\0'; 172 printf("ppb: <PnP> len=%d, %s\n", len, str); 173 printf("ppb: <PnP> nibble_1284_inbyte()=%d\n", 174 error); 175 } 176 goto end_detect; 177 } | 164 if ((error = ppb_1284_read_id(pnpdev, PPB_NIBBLE, str, 165 PPB_PnP_STRING_SIZE, &len))) 166 goto end_detect; |
178 | 167 |
179 if (len++ >= PPB_PnP_STRING_SIZE) { 180 printf("ppb: <PnP> not space left!\n"); 181 goto end_detect; 182 } 183 } 184 *q = '\0'; | 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 |
185 | 174 |
186 nibble_1284_sync(&pnpdev); 187 188 if (bootverbose) { 189 printf("ppb: <PnP> %d characters: ", len); 190 for (i = 0; i < len; i++) 191 printf("0x%x ", str[i]); 192 printf("\n"); 193 } 194 | |
195 /* replace ';' characters by '\0' */ 196 for (i = 0; i < len; i++) 197 str[i] = (str[i] == ';') ? '\0' : str[i]; 198 | 175 /* replace ';' characters by '\0' */ 176 for (i = 0; i < len; i++) 177 str[i] = (str[i] == ';') ? '\0' : str[i]; 178 |
199 if ((token = search_token(str, len, "MFG")) != NULL) | 179 if ((token = search_token(str, len, "MFG")) != NULL || 180 (token = search_token(str, len, "MANUFACTURER")) != NULL) |
200 printf("ppbus%d: <%s", ppb->ppb_link->adapter_unit, 201 search_token(token, UNKNOWN_LENGTH, ":") + 1); 202 else 203 printf("ppbus%d: <unknown", ppb->ppb_link->adapter_unit); 204 | 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 |
205 if ((token = search_token(str, len, "MDL")) != NULL) | 186 if ((token = search_token(str, len, "MDL")) != NULL || 187 (token = search_token(str, len, "MODEL")) != NULL) |
206 printf(" %s", 207 search_token(token, UNKNOWN_LENGTH, ":") + 1); 208 else 209 printf(" unknown"); 210 211 if ((token = search_token(str, len, "VER")) != NULL) 212 printf("/%s", 213 search_token(token, UNKNOWN_LENGTH, ":") + 1); --- 4 unchanged lines hidden (view full) --- 218 219 printf(">"); 220 221 if ((token = search_token(str, len, "CLS")) != NULL) { 222 class = search_token(token, UNKNOWN_LENGTH, ":") + 1; 223 printf(" %s", class); 224 } 225 | 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); --- 4 unchanged lines hidden (view full) --- 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 |
226 if ((token = search_token(str, len, "CMD")) != NULL) | 208 if ((token = search_token(str, len, "CMD")) != NULL || 209 (token = search_token(str, len, "COMMAND")) != NULL) |
227 printf(" %s", 228 search_token(token, UNKNOWN_LENGTH, ":") + 1); 229 230 printf("\n"); 231 232 if (class) 233 /* identify class ident */ 234 for (i = 0; pnp_tokens[i] != NULL; i++) { 235 if (search_token(class, len, pnp_tokens[i]) != NULL) { 236 class_id = i; 237 goto end_detect; 238 } 239 } 240 241 class_id = PPB_PnP_UNKNOWN; 242 243end_detect: | 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 226end_detect: |
244 if ((error = ppb_1284_terminate(&pnpdev, VALID_STATE)) && bootverbose) 245 printf("ppb: ppb_1284_terminate()=%d\n", error); | 227 return (class_id); 228} |
246 | 229 |
230/* 231 * ppb_scan_bus() 232 * 233 * Scan the ppbus for IEEE1284 compliant devices 234 */ 235static int 236ppb_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 |
|
247 ppb_release_bus(&pnpdev); | 326 ppb_release_bus(&pnpdev); |
248 return (class_id); | 327 328 return (0); 329 330end_scan: 331 ppb_release_bus(&pnpdev); 332 return (error); |
249} 250 | 333} 334 |
335#endif /* !DONTPROBE_1284 */ 336 |
|
251/* 252 * ppb_attachdevs() 253 * 254 * Called by ppcattach(), this function probes the ppbus and 255 * attaches found devices. 256 */ 257int 258ppb_attachdevs(struct ppb_data *ppb) 259{ 260 struct ppb_device *dev; 261 struct ppb_driver **p_drvpp, *p_drvp; 262 263 LIST_INIT(&ppb->ppb_devs); /* initialise device/driver list */ 264 p_drvpp = (struct ppb_driver **)ppbdriver_set.ls_items; 265 | 337/* 338 * ppb_attachdevs() 339 * 340 * Called by ppcattach(), this function probes the ppbus and 341 * attaches found devices. 342 */ 343int 344ppb_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 |
266/* XXX wait for ieee1284 good support */ 267#if 0 268 /* detect PnP devices */ 269 ppb->class_id = ppb_pnp_detect(ppb); 270#endif | 352#ifndef DONTPROBE_1284 353 /* detect IEEE1284 compliant devices */ 354 ppb_scan_bus(ppb); 355#endif /* !DONTPROBE_1284 */ |
271 272 /* 273 * Blindly try all probes here. Later we should look at 274 * the parallel-port PnP standard, and intelligently seek 275 * drivers based on configuration first. 276 */ 277 while ((p_drvp = *p_drvpp++) != NULL) { 278 if (p_drvp->probe && (dev = (p_drvp->probe(ppb))) != NULL) { --- 176 unchanged lines hidden --- | 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) { --- 176 unchanged lines hidden --- |