cardbus_cis.c (151785) | cardbus_cis.c (153811) |
---|---|
1/*- 2 * Copyright (c) 2000,2001 Jonathan Chen. 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 --- 11 unchanged lines hidden (view full) --- 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 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2000,2001 Jonathan Chen. 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 --- 11 unchanged lines hidden (view full) --- 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 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/cardbus/cardbus_cis.c 151785 2005-10-28 05:55:52Z imp $"); | 28__FBSDID("$FreeBSD: head/sys/dev/cardbus/cardbus_cis.c 153811 2005-12-29 01:43:47Z imp $"); |
29 30/* 31 * CIS Handling for the Cardbus Bus 32 */ 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> --- 16 unchanged lines hidden (view full) --- 53#include <dev/cardbus/cardbusvar.h> 54#include <dev/cardbus/cardbus_cis.h> 55 56extern int cardbus_cis_debug; 57 58#define DPRINTF(a) if (cardbus_cis_debug) printf a 59#define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x 60 | 29 30/* 31 * CIS Handling for the Cardbus Bus 32 */ 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> --- 16 unchanged lines hidden (view full) --- 53#include <dev/cardbus/cardbusvar.h> 54#include <dev/cardbus/cardbus_cis.h> 55 56extern int cardbus_cis_debug; 57 58#define DPRINTF(a) if (cardbus_cis_debug) printf a 59#define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x 60 |
61struct tuple_callbacks; 62 63typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len, 64 uint8_t *tupledata, uint32_t start, uint32_t *off, 65 struct tuple_callbacks *info); 66 67struct tuple_callbacks { 68 int id; 69 char *name; 70 tuple_cb *func; 71}; 72 | |
73static int decode_tuple_generic(device_t cbdev, device_t child, int id, 74 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 61static int decode_tuple_generic(device_t cbdev, device_t child, int id, 62 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
75 struct tuple_callbacks *info); | 63 struct tuple_callbacks *info, void *); |
76static int decode_tuple_linktarget(device_t cbdev, device_t child, int id, 77 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 64static int decode_tuple_linktarget(device_t cbdev, device_t child, int id, 65 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
78 struct tuple_callbacks *info); | 66 struct tuple_callbacks *info, void *); |
79static int decode_tuple_vers_1(device_t cbdev, device_t child, int id, 80 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 67static int decode_tuple_vers_1(device_t cbdev, device_t child, int id, 68 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
81 struct tuple_callbacks *info); | 69 struct tuple_callbacks *info, void *); |
82static int decode_tuple_funcid(device_t cbdev, device_t child, int id, 83 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 70static int decode_tuple_funcid(device_t cbdev, device_t child, int id, 71 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
84 struct tuple_callbacks *info); | 72 struct tuple_callbacks *info, void *); |
85static int decode_tuple_manfid(device_t cbdev, device_t child, int id, 86 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 73static int decode_tuple_manfid(device_t cbdev, device_t child, int id, 74 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
87 struct tuple_callbacks *info); | 75 struct tuple_callbacks *info, void *); |
88static int decode_tuple_funce(device_t cbdev, device_t child, int id, 89 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 76static int decode_tuple_funce(device_t cbdev, device_t child, int id, 77 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
90 struct tuple_callbacks *info); | 78 struct tuple_callbacks *info, void *); |
91static int decode_tuple_bar(device_t cbdev, device_t child, int id, 92 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 79static int decode_tuple_bar(device_t cbdev, device_t child, int id, 80 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
93 struct tuple_callbacks *info); | 81 struct tuple_callbacks *info, void *); |
94static int decode_tuple_unhandled(device_t cbdev, device_t child, int id, 95 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 82static int decode_tuple_unhandled(device_t cbdev, device_t child, int id, 83 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
96 struct tuple_callbacks *info); | 84 struct tuple_callbacks *info, void *); |
97static int decode_tuple_end(device_t cbdev, device_t child, int id, 98 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 85static int decode_tuple_end(device_t cbdev, device_t child, int id, 86 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
99 struct tuple_callbacks *info); | 87 struct tuple_callbacks *info, void *); |
100 101static int cardbus_read_tuple_conf(device_t cbdev, device_t child, 102 uint32_t start, uint32_t *off, int *tupleid, int *len, 103 uint8_t *tupledata); 104static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res, 105 uint32_t start, uint32_t *off, int *tupleid, int *len, 106 uint8_t *tupledata); 107static int cardbus_read_tuple(device_t cbdev, device_t child, 108 struct resource *res, uint32_t start, uint32_t *off, 109 int *tupleid, int *len, uint8_t *tupledata); 110static void cardbus_read_tuple_finish(device_t cbdev, device_t child, 111 int rid, struct resource *res); 112static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child, 113 uint32_t *start, int *rid); 114static int decode_tuple(device_t cbdev, device_t child, int tupleid, 115 int len, uint8_t *tupledata, uint32_t start, | 88 89static int cardbus_read_tuple_conf(device_t cbdev, device_t child, 90 uint32_t start, uint32_t *off, int *tupleid, int *len, 91 uint8_t *tupledata); 92static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res, 93 uint32_t start, uint32_t *off, int *tupleid, int *len, 94 uint8_t *tupledata); 95static int cardbus_read_tuple(device_t cbdev, device_t child, 96 struct resource *res, uint32_t start, uint32_t *off, 97 int *tupleid, int *len, uint8_t *tupledata); 98static void cardbus_read_tuple_finish(device_t cbdev, device_t child, 99 int rid, struct resource *res); 100static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child, 101 uint32_t *start, int *rid); 102static int decode_tuple(device_t cbdev, device_t child, int tupleid, 103 int len, uint8_t *tupledata, uint32_t start, |
116 uint32_t *off, struct tuple_callbacks *callbacks); 117static int cardbus_parse_cis(device_t cbdev, device_t child, 118 struct tuple_callbacks *callbacks); | 104 uint32_t *off, struct tuple_callbacks *callbacks, 105 void *); |
119 120#define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC } 121 122static char *funcnames[] = { 123 "Multi-Functioned", 124 "Memory", 125 "Serial Port", 126 "Parallel Port", --- 7 unchanged lines hidden (view full) --- 134 135/* 136 * Handler functions for various CIS tuples 137 */ 138 139static int 140decode_tuple_generic(device_t cbdev, device_t child, int id, 141 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 106 107#define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC } 108 109static char *funcnames[] = { 110 "Multi-Functioned", 111 "Memory", 112 "Serial Port", 113 "Parallel Port", --- 7 unchanged lines hidden (view full) --- 121 122/* 123 * Handler functions for various CIS tuples 124 */ 125 126static int 127decode_tuple_generic(device_t cbdev, device_t child, int id, 128 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
142 struct tuple_callbacks *info) | 129 struct tuple_callbacks *info, void *argp) |
143{ 144 int i; 145 146 if (cardbus_cis_debug) { 147 if (info) 148 printf("TUPLE: %s [%d]:", info->name, len); 149 else 150 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len); --- 6 unchanged lines hidden (view full) --- 157 printf("\n"); 158 } 159 return (0); 160} 161 162static int 163decode_tuple_linktarget(device_t cbdev, device_t child, int id, 164 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 130{ 131 int i; 132 133 if (cardbus_cis_debug) { 134 if (info) 135 printf("TUPLE: %s [%d]:", info->name, len); 136 else 137 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len); --- 6 unchanged lines hidden (view full) --- 144 printf("\n"); 145 } 146 return (0); 147} 148 149static int 150decode_tuple_linktarget(device_t cbdev, device_t child, int id, 151 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
165 struct tuple_callbacks *info) | 152 struct tuple_callbacks *info, void *argp) |
166{ 167 int i; 168 169 if (cardbus_cis_debug) { 170 printf("TUPLE: %s [%d]:", info->name, len); 171 172 for (i = 0; i < len; i++) { 173 if (i % 0x10 == 0 && len > 0x10) 174 printf("\n 0x%02x:", i); 175 printf(" %02x", tupledata[i]); 176 } 177 printf("\n"); 178 } 179 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' || 180 tupledata[2] != 'S') { 181 printf("Invalid data for CIS Link Target!\n"); 182 decode_tuple_generic(cbdev, child, id, len, tupledata, | 153{ 154 int i; 155 156 if (cardbus_cis_debug) { 157 printf("TUPLE: %s [%d]:", info->name, len); 158 159 for (i = 0; i < len; i++) { 160 if (i % 0x10 == 0 && len > 0x10) 161 printf("\n 0x%02x:", i); 162 printf(" %02x", tupledata[i]); 163 } 164 printf("\n"); 165 } 166 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' || 167 tupledata[2] != 'S') { 168 printf("Invalid data for CIS Link Target!\n"); 169 decode_tuple_generic(cbdev, child, id, len, tupledata, |
183 start, off, info); | 170 start, off, info, argp); |
184 return (EINVAL); 185 } 186 return (0); 187} 188 189static int 190decode_tuple_vers_1(device_t cbdev, device_t child, int id, 191 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 171 return (EINVAL); 172 } 173 return (0); 174} 175 176static int 177decode_tuple_vers_1(device_t cbdev, device_t child, int id, 178 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
192 struct tuple_callbacks *info) | 179 struct tuple_callbacks *info, void *argp) |
193{ 194 int i; 195 196 if (cardbus_cis_debug) { 197 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]); 198 printf("Product name: "); 199 for (i = 2; i < len; i++) { 200 if (tupledata[i] == '\0') --- 6 unchanged lines hidden (view full) --- 207 printf("\n"); 208 } 209 return (0); 210} 211 212static int 213decode_tuple_funcid(device_t cbdev, device_t child, int id, 214 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 180{ 181 int i; 182 183 if (cardbus_cis_debug) { 184 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]); 185 printf("Product name: "); 186 for (i = 2; i < len; i++) { 187 if (tupledata[i] == '\0') --- 6 unchanged lines hidden (view full) --- 194 printf("\n"); 195 } 196 return (0); 197} 198 199static int 200decode_tuple_funcid(device_t cbdev, device_t child, int id, 201 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
215 struct tuple_callbacks *info) | 202 struct tuple_callbacks *info, void *argp) |
216{ 217 struct cardbus_devinfo *dinfo = device_get_ivars(child); 218 int numnames = sizeof(funcnames) / sizeof(funcnames[0]); 219 int i; 220 221 if (cardbus_cis_debug) { 222 printf("Functions: "); 223 for (i = 0; i < len; i++) { 224 if (tupledata[i] < numnames) 225 printf("%s", funcnames[tupledata[i]]); 226 else 227 printf("Unknown(%d)", tupledata[i]); | 203{ 204 struct cardbus_devinfo *dinfo = device_get_ivars(child); 205 int numnames = sizeof(funcnames) / sizeof(funcnames[0]); 206 int i; 207 208 if (cardbus_cis_debug) { 209 printf("Functions: "); 210 for (i = 0; i < len; i++) { 211 if (tupledata[i] < numnames) 212 printf("%s", funcnames[tupledata[i]]); 213 else 214 printf("Unknown(%d)", tupledata[i]); |
228 if (i < len-1) | 215 if (i < len - 1) |
229 printf(", "); 230 } 231 printf("\n"); 232 } 233 if (len > 0) 234 dinfo->funcid = tupledata[0]; /* use first in list */ 235 return (0); 236} 237 238static int 239decode_tuple_manfid(device_t cbdev, device_t child, int id, 240 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 216 printf(", "); 217 } 218 printf("\n"); 219 } 220 if (len > 0) 221 dinfo->funcid = tupledata[0]; /* use first in list */ 222 return (0); 223} 224 225static int 226decode_tuple_manfid(device_t cbdev, device_t child, int id, 227 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
241 struct tuple_callbacks *info) | 228 struct tuple_callbacks *info, void *argp) |
242{ 243 struct cardbus_devinfo *dinfo = device_get_ivars(child); 244 int i; 245 246 if (cardbus_cis_debug) { 247 printf("Manufacturer ID: "); 248 for (i = 0; i < len; i++) 249 printf("%02x", tupledata[i]); --- 5 unchanged lines hidden (view full) --- 255 dinfo->prodid = tupledata[3] | (tupledata[4] << 8); 256 } 257 return (0); 258} 259 260static int 261decode_tuple_funce(device_t cbdev, device_t child, int id, 262 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 229{ 230 struct cardbus_devinfo *dinfo = device_get_ivars(child); 231 int i; 232 233 if (cardbus_cis_debug) { 234 printf("Manufacturer ID: "); 235 for (i = 0; i < len; i++) 236 printf("%02x", tupledata[i]); --- 5 unchanged lines hidden (view full) --- 242 dinfo->prodid = tupledata[3] | (tupledata[4] << 8); 243 } 244 return (0); 245} 246 247static int 248decode_tuple_funce(device_t cbdev, device_t child, int id, 249 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
263 struct tuple_callbacks *info) | 250 struct tuple_callbacks *info, void *argp) |
264{ 265 struct cardbus_devinfo *dinfo = device_get_ivars(child); 266 int type, i; 267 268 if (cardbus_cis_debug) { 269 printf("Function Extension: "); 270 for (i = 0; i < len; i++) 271 printf("%02x", tupledata[i]); --- 18 unchanged lines hidden (view full) --- 290 break; 291 } 292 return (0); 293} 294 295static int 296decode_tuple_bar(device_t cbdev, device_t child, int id, 297 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 251{ 252 struct cardbus_devinfo *dinfo = device_get_ivars(child); 253 int type, i; 254 255 if (cardbus_cis_debug) { 256 printf("Function Extension: "); 257 for (i = 0; i < len; i++) 258 printf("%02x", tupledata[i]); --- 18 unchanged lines hidden (view full) --- 277 break; 278 } 279 return (0); 280} 281 282static int 283decode_tuple_bar(device_t cbdev, device_t child, int id, 284 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
298 struct tuple_callbacks *info) | 285 struct tuple_callbacks *info, void *argp) |
299{ 300 struct cardbus_devinfo *dinfo = device_get_ivars(child); 301 int type; 302 uint8_t reg; 303 uint32_t bar, pci_bar; 304 305 if (len != 6) { 306 device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len); --- 78 unchanged lines hidden (view full) --- 385 */ 386 pci_enable_io(child, type); 387 return (0); 388} 389 390static int 391decode_tuple_unhandled(device_t cbdev, device_t child, int id, 392 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 286{ 287 struct cardbus_devinfo *dinfo = device_get_ivars(child); 288 int type; 289 uint8_t reg; 290 uint32_t bar, pci_bar; 291 292 if (len != 6) { 293 device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len); --- 78 unchanged lines hidden (view full) --- 372 */ 373 pci_enable_io(child, type); 374 return (0); 375} 376 377static int 378decode_tuple_unhandled(device_t cbdev, device_t child, int id, 379 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
393 struct tuple_callbacks *info) | 380 struct tuple_callbacks *info, void *argp) |
394{ 395 /* Make this message suck less XXX */ 396 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len); | 381{ 382 /* Make this message suck less XXX */ 383 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len); |
397 return (-1); | 384 return (EINVAL); |
398} 399 400static int 401decode_tuple_end(device_t cbdev, device_t child, int id, 402 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, | 385} 386 387static int 388decode_tuple_end(device_t cbdev, device_t child, int id, 389 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, |
403 struct tuple_callbacks *info) | 390 struct tuple_callbacks *info, void *argp) |
404{ 405 if (cardbus_cis_debug) 406 printf("CIS reading done\n"); 407 return (0); 408} 409 410/* 411 * Functions to read the a tuple from the card --- 62 unchanged lines hidden (view full) --- 474} 475 476static void 477cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid, 478 struct resource *res) 479{ 480 if (res != (struct resource*)~0UL) { 481 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); | 391{ 392 if (cardbus_cis_debug) 393 printf("CIS reading done\n"); 394 return (0); 395} 396 397/* 398 * Functions to read the a tuple from the card --- 62 unchanged lines hidden (view full) --- 461} 462 463static void 464cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid, 465 struct resource *res) 466{ 467 if (res != (struct resource*)~0UL) { 468 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); |
482 pci_write_config(child, rid, 0, 4); 483 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY); | 469 if (rid == PCIM_CIS_ASI_ROM) 470 pci_write_config(child, rid, pci_read_config(child, 471 rid, 4) & ~PCIR_BIOS, 4); |
484 } 485} 486 487static struct resource * 488cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, 489 int *rid) 490{ | 472 } 473} 474 475static struct resource * 476cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, 477 int *rid) 478{ |
491 uint32_t testval; 492 uint32_t size; | |
493 struct resource *res; 494 uint32_t space; 495 496 space = *start & PCIM_CIS_ASI_MASK; 497 switch (space) { 498 case PCIM_CIS_ASI_TUPLE: | 479 struct resource *res; 480 uint32_t space; 481 482 space = *start & PCIM_CIS_ASI_MASK; 483 switch (space) { 484 case PCIM_CIS_ASI_TUPLE: |
485 if (cardbus_cis_debug) 486 device_printf(cbdev, "CIS in PCI config space\n"); |
|
499 /* CIS in PCI config space need no initialization */ 500 return ((struct resource*)~0UL); 501 case PCIM_CIS_ASI_BAR0: 502 case PCIM_CIS_ASI_BAR1: 503 case PCIM_CIS_ASI_BAR2: 504 case PCIM_CIS_ASI_BAR3: 505 case PCIM_CIS_ASI_BAR4: 506 case PCIM_CIS_ASI_BAR5: 507 *rid = PCIR_BAR(space - PCIM_CIS_ASI_BAR0); | 487 /* CIS in PCI config space need no initialization */ 488 return ((struct resource*)~0UL); 489 case PCIM_CIS_ASI_BAR0: 490 case PCIM_CIS_ASI_BAR1: 491 case PCIM_CIS_ASI_BAR2: 492 case PCIM_CIS_ASI_BAR3: 493 case PCIM_CIS_ASI_BAR4: 494 case PCIM_CIS_ASI_BAR5: 495 *rid = PCIR_BAR(space - PCIM_CIS_ASI_BAR0); |
496 if (cardbus_cis_debug) 497 device_printf(cbdev, "CIS in BAR %#x\n", *rid); |
|
508 break; 509 case PCIM_CIS_ASI_ROM: 510 *rid = PCIR_BIOS; | 498 break; 499 case PCIM_CIS_ASI_ROM: 500 *rid = PCIR_BIOS; |
501 if (cardbus_cis_debug) 502 device_printf(cbdev, "CIS in option rom\n"); |
|
511 break; 512 default: 513 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n", 514 space); 515 return (NULL); 516 } 517 | 503 break; 504 default: 505 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n", 506 space); 507 return (NULL); 508 } 509 |
518 /* figure out how much space we need */ 519 pci_write_config(child, *rid, 0xffffffff, 4); 520 testval = pci_read_config(child, *rid, 4); 521 522 /* 523 * This bit has a different meaning depending if we are dealing 524 * with a normal BAR or an Option ROM BAR. 525 */ 526 if (((testval & 0x1) == 0x1) && (*rid != PCIR_BIOS)) { 527 device_printf(cbdev, "CIS Space is IO, expecting memory.\n"); 528 return (NULL); 529 } 530 531 size = CARDBUS_MAPREG_MEM_SIZE(testval); 532 /* XXX Is this some kind of hack? */ 533 if (size < 4096) 534 size = 4096; | |
535 /* allocate the memory space to read CIS */ | 510 /* allocate the memory space to read CIS */ |
536 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size, 537 rman_make_alignment_flags(size) | RF_ACTIVE); | 511 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, 1, 512 rman_make_alignment_flags(4096) | RF_ACTIVE); |
538 if (res == NULL) { 539 device_printf(cbdev, "Unable to allocate resource " 540 "to read CIS.\n"); 541 return (NULL); 542 } | 513 if (res == NULL) { 514 device_printf(cbdev, "Unable to allocate resource " 515 "to read CIS.\n"); 516 return (NULL); 517 } |
543 pci_write_config(child, *rid, 544 rman_get_start(res) | ((*rid == PCIR_BIOS) ? PCIM_BIOS_ENABLE : 0), 545 4); | |
546 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY); | 518 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY); |
519 pci_write_config(child, *rid, rman_get_start(res), 4); 520 if (*rid == PCIR_BIOS) 521 pci_write_config(child, *rid, 522 rman_get_start(res) | PCIM_BIOS_ENABLE, 4); |
|
547 548 /* Flip to the right ROM image if CIS is in ROM */ 549 if (space == PCIM_CIS_ASI_ROM) { 550 bus_space_tag_t bt; 551 bus_space_handle_t bh; 552 uint32_t imagesize; 553 uint32_t imagebase = 0; 554 uint32_t pcidata; --- 66 unchanged lines hidden (view full) --- 621 622/* 623 * Dispatch the right handler function per tuple 624 */ 625 626static int 627decode_tuple(device_t cbdev, device_t child, int tupleid, int len, 628 uint8_t *tupledata, uint32_t start, uint32_t *off, | 523 524 /* Flip to the right ROM image if CIS is in ROM */ 525 if (space == PCIM_CIS_ASI_ROM) { 526 bus_space_tag_t bt; 527 bus_space_handle_t bh; 528 uint32_t imagesize; 529 uint32_t imagebase = 0; 530 uint32_t pcidata; --- 66 unchanged lines hidden (view full) --- 597 598/* 599 * Dispatch the right handler function per tuple 600 */ 601 602static int 603decode_tuple(device_t cbdev, device_t child, int tupleid, int len, 604 uint8_t *tupledata, uint32_t start, uint32_t *off, |
629 struct tuple_callbacks *callbacks) | 605 struct tuple_callbacks *callbacks, void *argp) |
630{ 631 int i; 632 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) { 633 if (tupleid == callbacks[i].id) 634 return (callbacks[i].func(cbdev, child, tupleid, len, | 606{ 607 int i; 608 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) { 609 if (tupleid == callbacks[i].id) 610 return (callbacks[i].func(cbdev, child, tupleid, len, |
635 tupledata, start, off, &callbacks[i])); | 611 tupledata, start, off, &callbacks[i], argp)); |
636 } 637 return (callbacks[i].func(cbdev, child, tupleid, len, | 612 } 613 return (callbacks[i].func(cbdev, child, tupleid, len, |
638 tupledata, start, off, NULL)); | 614 tupledata, start, off, NULL, argp)); |
639} 640 | 615} 616 |
641static int | 617int |
642cardbus_parse_cis(device_t cbdev, device_t child, | 618cardbus_parse_cis(device_t cbdev, device_t child, |
643 struct tuple_callbacks *callbacks) | 619 struct tuple_callbacks *callbacks, void *argp) |
644{ 645 uint8_t tupledata[MAXTUPLESIZE]; 646 int tupleid; 647 int len; 648 int expect_linktarget; 649 uint32_t start, off; 650 struct resource *res; 651 int rid; 652 653 bzero(tupledata, MAXTUPLESIZE); 654 expect_linktarget = TRUE; 655 if ((start = pci_read_config(child, PCIR_CIS, 4)) == 0) { 656 device_printf(cbdev, "CIS pointer is 0!\n"); 657 return (ENXIO); 658 } | 620{ 621 uint8_t tupledata[MAXTUPLESIZE]; 622 int tupleid; 623 int len; 624 int expect_linktarget; 625 uint32_t start, off; 626 struct resource *res; 627 int rid; 628 629 bzero(tupledata, MAXTUPLESIZE); 630 expect_linktarget = TRUE; 631 if ((start = pci_read_config(child, PCIR_CIS, 4)) == 0) { 632 device_printf(cbdev, "CIS pointer is 0!\n"); 633 return (ENXIO); 634 } |
635 if (cardbus_cis_debug) 636 device_printf(cbdev, "CIS pointer is %#x\n", start); |
|
659 off = 0; 660 res = cardbus_read_tuple_init(cbdev, child, &start, &rid); 661 if (res == NULL) { 662 device_printf(cbdev, "Unable to allocate resources for CIS\n"); 663 return (ENXIO); 664 } 665 666 do { | 637 off = 0; 638 res = cardbus_read_tuple_init(cbdev, child, &start, &rid); 639 if (res == NULL) { 640 device_printf(cbdev, "Unable to allocate resources for CIS\n"); 641 return (ENXIO); 642 } 643 644 do { |
667 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off, 668 &tupleid, &len, tupledata)) { | 645 if (cardbus_read_tuple(cbdev, child, res, start, &off, 646 &tupleid, &len, tupledata) != 0) { |
669 device_printf(cbdev, "Failed to read CIS.\n"); 670 cardbus_read_tuple_finish(cbdev, child, rid, res); 671 return (ENXIO); 672 } 673 674 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) { 675 device_printf(cbdev, "Expecting link target, got 0x%x\n", 676 tupleid); 677 cardbus_read_tuple_finish(cbdev, child, rid, res); 678 return (EINVAL); 679 } 680 expect_linktarget = decode_tuple(cbdev, child, tupleid, len, | 647 device_printf(cbdev, "Failed to read CIS.\n"); 648 cardbus_read_tuple_finish(cbdev, child, rid, res); 649 return (ENXIO); 650 } 651 652 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) { 653 device_printf(cbdev, "Expecting link target, got 0x%x\n", 654 tupleid); 655 cardbus_read_tuple_finish(cbdev, child, rid, res); 656 return (EINVAL); 657 } 658 expect_linktarget = decode_tuple(cbdev, child, tupleid, len, |
681 tupledata, start, &off, callbacks); | 659 tupledata, start, &off, callbacks, argp); |
682 if (expect_linktarget != 0) { 683 device_printf(cbdev, "Parsing failed with %d\n", 684 expect_linktarget); 685 cardbus_read_tuple_finish(cbdev, child, rid, res); 686 return (expect_linktarget); 687 } 688 } while (tupleid != CISTPL_END); 689 cardbus_read_tuple_finish(cbdev, child, rid, res); --- 15 unchanged lines hidden (view full) --- 705 MAKETUPLE(VERS_1, vers_1), 706 MAKETUPLE(MANFID, manfid), 707 MAKETUPLE(FUNCID, funcid), 708 MAKETUPLE(FUNCE, funce), 709 MAKETUPLE(END, end), 710 MAKETUPLE(GENERIC, generic), 711 }; 712 | 660 if (expect_linktarget != 0) { 661 device_printf(cbdev, "Parsing failed with %d\n", 662 expect_linktarget); 663 cardbus_read_tuple_finish(cbdev, child, rid, res); 664 return (expect_linktarget); 665 } 666 } while (tupleid != CISTPL_END); 667 cardbus_read_tuple_finish(cbdev, child, rid, res); --- 15 unchanged lines hidden (view full) --- 683 MAKETUPLE(VERS_1, vers_1), 684 MAKETUPLE(MANFID, manfid), 685 MAKETUPLE(FUNCID, funcid), 686 MAKETUPLE(FUNCE, funce), 687 MAKETUPLE(END, end), 688 MAKETUPLE(GENERIC, generic), 689 }; 690 |
713 ret = cardbus_parse_cis(cbdev, child, init_callbacks); | 691 ret = cardbus_parse_cis(cbdev, child, init_callbacks, NULL); |
714 if (ret < 0) 715 return (ret); 716 return 0; 717} | 692 if (ret < 0) 693 return (ret); 694 return 0; 695} |