hcd-uhci.c (e2f89926f19d2940eda070542501f39f51a8c81f) | hcd-uhci.c (f90c2bcdbc69e41e575f868b984c3e2de8f51bac) |
---|---|
1/* 2 * USB UHCI controller emulation 3 * 4 * Copyright (c) 2005 Fabrice Bellard 5 * 6 * Copyright (c) 2008 Max Krasnyansky 7 * Magor rewrite of the UHCI data structures parser and frame processor 8 * Support for fully async operation and multiple outstanding transactions --- 117 unchanged lines hidden (view full) --- 126 uint16_t status; 127 uint16_t intr; /* interrupt enable register */ 128 uint16_t frnum; /* frame number */ 129 uint32_t fl_base_addr; /* frame list base address */ 130 uint8_t sof_timing; 131 uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ 132 int64_t expire_time; 133 QEMUTimer *frame_timer; | 1/* 2 * USB UHCI controller emulation 3 * 4 * Copyright (c) 2005 Fabrice Bellard 5 * 6 * Copyright (c) 2008 Max Krasnyansky 7 * Magor rewrite of the UHCI data structures parser and frame processor 8 * Support for fully async operation and multiple outstanding transactions --- 117 unchanged lines hidden (view full) --- 126 uint16_t status; 127 uint16_t intr; /* interrupt enable register */ 128 uint16_t frnum; /* frame number */ 129 uint32_t fl_base_addr; /* frame list base address */ 130 uint8_t sof_timing; 131 uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ 132 int64_t expire_time; 133 QEMUTimer *frame_timer; |
134 QEMUBH *bh; 135 uint32_t frame_bytes; 136 uint32_t frame_bandwidth; | |
137 UHCIPort ports[NB_PORTS]; 138 139 /* Interrupts that should be raised at the end of the current frame. */ 140 uint32_t pending_int_mask; | 134 UHCIPort ports[NB_PORTS]; 135 136 /* Interrupts that should be raised at the end of the current frame. */ 137 uint32_t pending_int_mask; |
141 int irq_pin; | |
142 143 /* Active packets */ 144 QTAILQ_HEAD(, UHCIQueue) queues; 145 uint8_t num_ports_vmstate; 146 147 /* Properties */ 148 char *masterbus; 149 uint32_t firstport; --- 137 unchanged lines hidden (view full) --- 287 uhci_async_unlink(curr); 288 uhci_async_cancel(curr); 289 } 290 } 291} 292 293static void uhci_async_cancel_all(UHCIState *s) 294{ | 138 139 /* Active packets */ 140 QTAILQ_HEAD(, UHCIQueue) queues; 141 uint8_t num_ports_vmstate; 142 143 /* Properties */ 144 char *masterbus; 145 uint32_t firstport; --- 137 unchanged lines hidden (view full) --- 283 uhci_async_unlink(curr); 284 uhci_async_cancel(curr); 285 } 286 } 287} 288 289static void uhci_async_cancel_all(UHCIState *s) 290{ |
295 UHCIQueue *queue, *nq; | 291 UHCIQueue *queue; |
296 UHCIAsync *curr, *n; 297 | 292 UHCIAsync *curr, *n; 293 |
298 QTAILQ_FOREACH_SAFE(queue, &s->queues, next, nq) { | 294 QTAILQ_FOREACH(queue, &s->queues, next) { |
299 QTAILQ_FOREACH_SAFE(curr, &queue->asyncs, next, n) { 300 uhci_async_unlink(curr); 301 uhci_async_cancel(curr); 302 } 303 uhci_queue_free(queue); 304 } 305} 306 --- 29 unchanged lines hidden (view full) --- 336 ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) || 337 ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) || 338 (s->status & UHCI_STS_HSERR) || 339 (s->status & UHCI_STS_HCPERR)) { 340 level = 1; 341 } else { 342 level = 0; 343 } | 295 QTAILQ_FOREACH_SAFE(curr, &queue->asyncs, next, n) { 296 uhci_async_unlink(curr); 297 uhci_async_cancel(curr); 298 } 299 uhci_queue_free(queue); 300 } 301} 302 --- 29 unchanged lines hidden (view full) --- 332 ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) || 333 ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) || 334 (s->status & UHCI_STS_HSERR) || 335 (s->status & UHCI_STS_HCPERR)) { 336 level = 1; 337 } else { 338 level = 0; 339 } |
344 qemu_set_irq(s->dev.irq[s->irq_pin], level); | 340 qemu_set_irq(s->dev.irq[3], level); |
345} 346 347static void uhci_reset(void *opaque) 348{ 349 UHCIState *s = opaque; 350 uint8_t *pci_conf; 351 int i; 352 UHCIPort *port; --- 15 unchanged lines hidden (view full) --- 368 port = &s->ports[i]; 369 port->ctrl = 0x0080; 370 if (port->port.dev && port->port.dev->attached) { 371 usb_port_reset(&port->port); 372 } 373 } 374 375 uhci_async_cancel_all(s); | 341} 342 343static void uhci_reset(void *opaque) 344{ 345 UHCIState *s = opaque; 346 uint8_t *pci_conf; 347 int i; 348 UHCIPort *port; --- 15 unchanged lines hidden (view full) --- 364 port = &s->ports[i]; 365 port->ctrl = 0x0080; 366 if (port->port.dev && port->port.dev->attached) { 367 usb_port_reset(&port->port); 368 } 369 } 370 371 uhci_async_cancel_all(s); |
376 qemu_bh_cancel(s->bh); | |
377 uhci_update_irq(s); 378} 379 | 372 uhci_update_irq(s); 373} 374 |
375static void uhci_pre_save(void *opaque) 376{ 377 UHCIState *s = opaque; 378 379 uhci_async_cancel_all(s); 380} 381 |
|
380static const VMStateDescription vmstate_uhci_port = { 381 .name = "uhci port", 382 .version_id = 1, 383 .minimum_version_id = 1, 384 .minimum_version_id_old = 1, 385 .fields = (VMStateField []) { 386 VMSTATE_UINT16(ctrl, UHCIPort), 387 VMSTATE_END_OF_LIST() 388 } 389}; 390 391static const VMStateDescription vmstate_uhci = { 392 .name = "uhci", 393 .version_id = 2, 394 .minimum_version_id = 1, 395 .minimum_version_id_old = 1, | 382static const VMStateDescription vmstate_uhci_port = { 383 .name = "uhci port", 384 .version_id = 1, 385 .minimum_version_id = 1, 386 .minimum_version_id_old = 1, 387 .fields = (VMStateField []) { 388 VMSTATE_UINT16(ctrl, UHCIPort), 389 VMSTATE_END_OF_LIST() 390 } 391}; 392 393static const VMStateDescription vmstate_uhci = { 394 .name = "uhci", 395 .version_id = 2, 396 .minimum_version_id = 1, 397 .minimum_version_id_old = 1, |
398 .pre_save = uhci_pre_save, |
|
396 .fields = (VMStateField []) { 397 VMSTATE_PCI_DEVICE(dev, UHCIState), 398 VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState), 399 VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1, 400 vmstate_uhci_port, UHCIPort), 401 VMSTATE_UINT16(cmd, UHCIState), 402 VMSTATE_UINT16(status, UHCIState), 403 VMSTATE_UINT16(intr, UHCIState), --- 462 unchanged lines hidden (view full) --- 866 uhci_async_link(async); 867 return TD_RESULT_ASYNC_START; 868 } 869 870 async->packet.result = len; 871 872done: 873 len = uhci_complete_td(s, td, async, int_mask); | 399 .fields = (VMStateField []) { 400 VMSTATE_PCI_DEVICE(dev, UHCIState), 401 VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState), 402 VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1, 403 vmstate_uhci_port, UHCIPort), 404 VMSTATE_UINT16(cmd, UHCIState), 405 VMSTATE_UINT16(status, UHCIState), 406 VMSTATE_UINT16(intr, UHCIState), --- 462 unchanged lines hidden (view full) --- 869 uhci_async_link(async); 870 return TD_RESULT_ASYNC_START; 871 } 872 873 async->packet.result = len; 874 875done: 876 len = uhci_complete_td(s, td, async, int_mask); |
874 usb_packet_unmap(&async->packet, &async->sgl); | 877 usb_packet_unmap(&async->packet); |
875 uhci_async_free(async); 876 return len; 877} 878 879static void uhci_async_complete(USBPort *port, USBPacket *packet) 880{ 881 UHCIAsync *async = container_of(packet, UHCIAsync, packet); 882 UHCIState *s = async->queue->uhci; --- 14 unchanged lines hidden (view full) --- 897 s->pending_int_mask |= int_mask; 898 899 /* update the status bits of the TD */ 900 val = cpu_to_le32(td.ctrl); 901 pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val)); 902 uhci_async_free(async); 903 } else { 904 async->done = 1; | 878 uhci_async_free(async); 879 return len; 880} 881 882static void uhci_async_complete(USBPort *port, USBPacket *packet) 883{ 884 UHCIAsync *async = container_of(packet, UHCIAsync, packet); 885 UHCIState *s = async->queue->uhci; --- 14 unchanged lines hidden (view full) --- 900 s->pending_int_mask |= int_mask; 901 902 /* update the status bits of the TD */ 903 val = cpu_to_le32(td.ctrl); 904 pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val)); 905 uhci_async_free(async); 906 } else { 907 async->done = 1; |
905 if (s->frame_bytes < s->frame_bandwidth) { 906 qemu_bh_schedule(s->bh); 907 } | 908 uhci_process_frame(s); |
908 } 909} 910 911static int is_valid(uint32_t link) 912{ 913 return (link & 1) == 0; 914} 915 --- 63 unchanged lines hidden (view full) --- 979 assert(int_mask == 0); 980 plink = ptd.link; 981 } 982} 983 984static void uhci_process_frame(UHCIState *s) 985{ 986 uint32_t frame_addr, link, old_td_ctrl, val, int_mask; | 909 } 910} 911 912static int is_valid(uint32_t link) 913{ 914 return (link & 1) == 0; 915} 916 --- 63 unchanged lines hidden (view full) --- 980 assert(int_mask == 0); 981 plink = ptd.link; 982 } 983} 984 985static void uhci_process_frame(UHCIState *s) 986{ 987 uint32_t frame_addr, link, old_td_ctrl, val, int_mask; |
987 uint32_t curr_qh, td_count = 0; | 988 uint32_t curr_qh, td_count = 0, bytes_count = 0; |
988 int cnt, ret; 989 UHCI_TD td; 990 UHCI_QH qh; 991 QhDb qhdb; 992 993 frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2); 994 995 pci_dma_read(&s->dev, frame_addr, &link, 4); 996 le32_to_cpus(&link); 997 998 int_mask = 0; 999 curr_qh = 0; 1000 1001 qhdb_reset(&qhdb); 1002 1003 for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) { | 989 int cnt, ret; 990 UHCI_TD td; 991 UHCI_QH qh; 992 QhDb qhdb; 993 994 frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2); 995 996 pci_dma_read(&s->dev, frame_addr, &link, 4); 997 le32_to_cpus(&link); 998 999 int_mask = 0; 1000 curr_qh = 0; 1001 1002 qhdb_reset(&qhdb); 1003 1004 for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) { |
1004 if (s->frame_bytes >= s->frame_bandwidth) { 1005 /* We've reached the usb 1.1 bandwidth, which is 1006 1280 bytes/frame, stop processing */ 1007 trace_usb_uhci_frame_stop_bandwidth(); 1008 break; 1009 } | |
1010 if (is_qh(link)) { 1011 /* QH */ 1012 trace_usb_uhci_qh_load(link & ~0xf); 1013 1014 if (qhdb_insert(&qhdb, link)) { 1015 /* 1016 * We're going in circles. Which is not a bug because 1017 * HCD is allowed to do that as part of the BW management. 1018 * | 1005 if (is_qh(link)) { 1006 /* QH */ 1007 trace_usb_uhci_qh_load(link & ~0xf); 1008 1009 if (qhdb_insert(&qhdb, link)) { 1010 /* 1011 * We're going in circles. Which is not a bug because 1012 * HCD is allowed to do that as part of the BW management. 1013 * |
1019 * Stop processing here if no transaction has been done 1020 * since we've been here last time. | 1014 * Stop processing here if 1015 * (a) no transaction has been done since we've been 1016 * here last time, or 1017 * (b) we've reached the usb 1.1 bandwidth, which is 1018 * 1280 bytes/frame. |
1021 */ 1022 if (td_count == 0) { 1023 trace_usb_uhci_frame_loop_stop_idle(); 1024 break; | 1019 */ 1020 if (td_count == 0) { 1021 trace_usb_uhci_frame_loop_stop_idle(); 1022 break; |
1023 } else if (bytes_count >= 1280) { 1024 trace_usb_uhci_frame_loop_stop_bandwidth(); 1025 break; |
|
1025 } else { 1026 trace_usb_uhci_frame_loop_continue(); 1027 td_count = 0; 1028 qhdb_reset(&qhdb); 1029 qhdb_insert(&qhdb, link); 1030 } 1031 } 1032 --- 46 unchanged lines hidden (view full) --- 1079 } 1080 link = curr_qh ? qh.link : td.link; 1081 continue; 1082 1083 case TD_RESULT_COMPLETE: 1084 trace_usb_uhci_td_complete(curr_qh & ~0xf, link & ~0xf); 1085 link = td.link; 1086 td_count++; | 1026 } else { 1027 trace_usb_uhci_frame_loop_continue(); 1028 td_count = 0; 1029 qhdb_reset(&qhdb); 1030 qhdb_insert(&qhdb, link); 1031 } 1032 } 1033 --- 46 unchanged lines hidden (view full) --- 1080 } 1081 link = curr_qh ? qh.link : td.link; 1082 continue; 1083 1084 case TD_RESULT_COMPLETE: 1085 trace_usb_uhci_td_complete(curr_qh & ~0xf, link & ~0xf); 1086 link = td.link; 1087 td_count++; |
1087 s->frame_bytes += (td.ctrl & 0x7ff) + 1; | 1088 bytes_count += (td.ctrl & 0x7ff) + 1; |
1088 1089 if (curr_qh) { 1090 /* update QH element link */ 1091 qh.el_link = link; 1092 val = cpu_to_le32(qh.el_link); 1093 pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4, &val, sizeof(val)); 1094 1095 if (!depth_first(link)) { --- 10 unchanged lines hidden (view full) --- 1106 1107 /* go to the next entry */ 1108 } 1109 1110out: 1111 s->pending_int_mask |= int_mask; 1112} 1113 | 1089 1090 if (curr_qh) { 1091 /* update QH element link */ 1092 qh.el_link = link; 1093 val = cpu_to_le32(qh.el_link); 1094 pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4, &val, sizeof(val)); 1095 1096 if (!depth_first(link)) { --- 10 unchanged lines hidden (view full) --- 1107 1108 /* go to the next entry */ 1109 } 1110 1111out: 1112 s->pending_int_mask |= int_mask; 1113} 1114 |
1114static void uhci_bh(void *opaque) 1115{ 1116 UHCIState *s = opaque; 1117 uhci_process_frame(s); 1118} 1119 | |
1120static void uhci_frame_timer(void *opaque) 1121{ 1122 UHCIState *s = opaque; 1123 1124 /* prepare the timer for the next frame */ 1125 s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ); | 1115static void uhci_frame_timer(void *opaque) 1116{ 1117 UHCIState *s = opaque; 1118 1119 /* prepare the timer for the next frame */ 1120 s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ); |
1126 s->frame_bytes = 0; 1127 qemu_bh_cancel(s->bh); | |
1128 1129 if (!(s->cmd & UHCI_CMD_RS)) { 1130 /* Full stop */ 1131 trace_usb_uhci_schedule_stop(); 1132 qemu_del_timer(s->frame_timer); 1133 uhci_async_cancel_all(s); 1134 /* set hchalted bit in status - UHCI11D 2.1.2 */ 1135 s->status |= UHCI_STS_HCHALTED; --- 44 unchanged lines hidden (view full) --- 1180 .complete = uhci_async_complete, 1181}; 1182 1183static USBBusOps uhci_bus_ops = { 1184}; 1185 1186static int usb_uhci_common_initfn(PCIDevice *dev) 1187{ | 1121 1122 if (!(s->cmd & UHCI_CMD_RS)) { 1123 /* Full stop */ 1124 trace_usb_uhci_schedule_stop(); 1125 qemu_del_timer(s->frame_timer); 1126 uhci_async_cancel_all(s); 1127 /* set hchalted bit in status - UHCI11D 2.1.2 */ 1128 s->status |= UHCI_STS_HCHALTED; --- 44 unchanged lines hidden (view full) --- 1173 .complete = uhci_async_complete, 1174}; 1175 1176static USBBusOps uhci_bus_ops = { 1177}; 1178 1179static int usb_uhci_common_initfn(PCIDevice *dev) 1180{ |
1188 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); | |
1189 UHCIState *s = DO_UPCAST(UHCIState, dev, dev); 1190 uint8_t *pci_conf = s->dev.config; 1191 int i; 1192 1193 pci_conf[PCI_CLASS_PROG] = 0x00; 1194 /* TODO: reset value should be 0. */ | 1181 UHCIState *s = DO_UPCAST(UHCIState, dev, dev); 1182 uint8_t *pci_conf = s->dev.config; 1183 int i; 1184 1185 pci_conf[PCI_CLASS_PROG] = 0x00; 1186 /* TODO: reset value should be 0. */ |
1187 pci_conf[PCI_INTERRUPT_PIN] = 4; /* interrupt pin D */ |
|
1195 pci_conf[USB_SBRN] = USB_RELEASE_1; // release number 1196 | 1188 pci_conf[USB_SBRN] = USB_RELEASE_1; // release number 1189 |
1197 switch (pc->device_id) { 1198 case PCI_DEVICE_ID_INTEL_82801I_UHCI1: 1199 s->irq_pin = 0; /* A */ 1200 break; 1201 case PCI_DEVICE_ID_INTEL_82801I_UHCI2: 1202 s->irq_pin = 1; /* B */ 1203 break; 1204 case PCI_DEVICE_ID_INTEL_82801I_UHCI3: 1205 s->irq_pin = 2; /* C */ 1206 break; 1207 default: 1208 s->irq_pin = 3; /* D */ 1209 break; 1210 } 1211 pci_config_set_interrupt_pin(pci_conf, s->irq_pin + 1); 1212 | |
1213 if (s->masterbus) { 1214 USBPort *ports[NB_PORTS]; 1215 for(i = 0; i < NB_PORTS; i++) { 1216 ports[i] = &s->ports[i].port; 1217 } 1218 if (usb_register_companion(s->masterbus, ports, NB_PORTS, 1219 s->firstport, s, &uhci_port_ops, 1220 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) { 1221 return -1; 1222 } 1223 } else { 1224 usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev); 1225 for (i = 0; i < NB_PORTS; i++) { 1226 usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops, 1227 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); 1228 } 1229 } | 1190 if (s->masterbus) { 1191 USBPort *ports[NB_PORTS]; 1192 for(i = 0; i < NB_PORTS; i++) { 1193 ports[i] = &s->ports[i].port; 1194 } 1195 if (usb_register_companion(s->masterbus, ports, NB_PORTS, 1196 s->firstport, s, &uhci_port_ops, 1197 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) { 1198 return -1; 1199 } 1200 } else { 1201 usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev); 1202 for (i = 0; i < NB_PORTS; i++) { 1203 usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops, 1204 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); 1205 } 1206 } |
1230 s->bh = qemu_bh_new(uhci_bh, s); | |
1231 s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s); 1232 s->num_ports_vmstate = NB_PORTS; 1233 QTAILQ_INIT(&s->queues); 1234 1235 qemu_register_reset(uhci_reset, s); 1236 1237 memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20); 1238 /* Use region 4 for consistency with real hardware. BSD guests seem --- 13 unchanged lines hidden (view full) --- 1252 /* PM capability */ 1253 pci_set_long(pci_conf + 0x80,0x00020001); 1254 /* USB legacy support */ 1255 pci_set_long(pci_conf + 0xc0,0x00002000); 1256 1257 return usb_uhci_common_initfn(dev); 1258} 1259 | 1207 s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s); 1208 s->num_ports_vmstate = NB_PORTS; 1209 QTAILQ_INIT(&s->queues); 1210 1211 qemu_register_reset(uhci_reset, s); 1212 1213 memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20); 1214 /* Use region 4 for consistency with real hardware. BSD guests seem --- 13 unchanged lines hidden (view full) --- 1228 /* PM capability */ 1229 pci_set_long(pci_conf + 0x80,0x00020001); 1230 /* USB legacy support */ 1231 pci_set_long(pci_conf + 0xc0,0x00002000); 1232 1233 return usb_uhci_common_initfn(dev); 1234} 1235 |
1260static int usb_uhci_exit(PCIDevice *dev) | 1236static void usb_uhci_exit(PCIDevice *dev) |
1261{ 1262 UHCIState *s = DO_UPCAST(UHCIState, dev, dev); 1263 1264 memory_region_destroy(&s->io_bar); | 1237{ 1238 UHCIState *s = DO_UPCAST(UHCIState, dev, dev); 1239 1240 memory_region_destroy(&s->io_bar); |
1265 return 0; | |
1266} 1267 1268static Property uhci_properties[] = { 1269 DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), 1270 DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), | 1241} 1242 1243static Property uhci_properties[] = { 1244 DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), 1245 DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), |
1271 DEFINE_PROP_UINT32("bandwidth", UHCIState, frame_bandwidth, 1280), | |
1272 DEFINE_PROP_END_OF_LIST(), 1273}; 1274 1275static void piix3_uhci_class_init(ObjectClass *klass, void *data) 1276{ 1277 DeviceClass *dc = DEVICE_CLASS(klass); 1278 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 1279 --- 135 unchanged lines hidden --- | 1246 DEFINE_PROP_END_OF_LIST(), 1247}; 1248 1249static void piix3_uhci_class_init(ObjectClass *klass, void *data) 1250{ 1251 DeviceClass *dc = DEVICE_CLASS(klass); 1252 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 1253 --- 135 unchanged lines hidden --- |