Changeset 5e598e0 in mainline
- Timestamp:
- 2010-04-07T20:55:50Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 89ce401a
- Parents:
- 8c06905
- Location:
- uspace
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libdrv/include/driver.h
r8c06905 r5e598e0 79 79 /** Globally unique device identifier (assigned to the device by the device manager). */ 80 80 device_handle_t handle; 81 /** The phone to the parent device driver .*/81 /** The phone to the parent device driver (if it is different from this driver).*/ 82 82 int parent_phone; 83 /** Parent device if handled by this driver, NULL otherwise. */ 84 device_t *parent; 83 85 /** The device's name.*/ 84 86 const char *name; -
uspace/srv/drivers/pciintel/pci.c
r8c06905 r5e598e0 41 41 #include <bool.h> 42 42 #include <fibril_synch.h> 43 #include <stdlib.h>44 43 #include <string.h> 45 44 #include <ctype.h> … … 53 52 #include <device/hw_res.h> 54 53 #include <ddi.h> 54 #include <libarch/ddi.h> 55 56 #include "pci.h" 57 #include "pci_regs.h" 55 58 56 59 #define NAME "pciintel" 60 61 62 #define CONF_ADDR(bus, dev, fn, reg) ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 63 57 64 58 65 static bool pci_add_device(device_t *dev); … … 75 82 void *conf_data_port; 76 83 void *conf_addr_port; 84 fibril_mutex_t conf_mutex; 77 85 } pci_bus_data_t; 78 86 87 static inline pci_bus_data_t *create_pci_bus_data() 88 { 89 pci_bus_data_t *bus_data = (pci_bus_data_t *)malloc(sizeof(pci_bus_data_t)); 90 if(NULL != bus_data) { 91 memset(bus_data, 0, sizeof(pci_bus_data_t)); 92 fibril_mutex_initialize(&bus_data->conf_mutex); 93 } 94 return bus_data; 95 } 96 97 static inline void delete_pci_bus_data(pci_bus_data_t *bus_data) 98 { 99 free(bus_data); 100 } 101 102 static void pci_conf_read(device_t *dev, int reg, uint8_t *buf, size_t len) 103 { 104 assert(NULL != dev->parent); 105 106 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 107 pci_bus_data_t *bus_data = (pci_bus_data_t *)dev->parent->driver_data; 108 109 fibril_mutex_lock(&bus_data->conf_mutex); 110 111 uint32_t conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg); 112 void *addr = bus_data->conf_data_port + (reg & 3); 113 114 pio_write_32(bus_data->conf_addr_port, conf_addr); 115 116 switch (len) { 117 case 1: 118 buf[0] = pio_read_8(addr); 119 break; 120 case 2: 121 ((uint16_t *)buf)[0] = pio_read_16(addr); 122 break; 123 case 4: 124 ((uint32_t *)buf)[0] = pio_read_32(addr); 125 break; 126 } 127 128 fibril_mutex_unlock(&bus_data->conf_mutex); 129 } 130 131 uint8_t pci_conf_read_8(device_t *dev, int reg) 132 { 133 uint8_t res; 134 pci_conf_read(dev, reg, &res, 1); 135 return res; 136 } 137 138 uint16_t pci_conf_read_16(device_t *dev, int reg) 139 { 140 uint16_t res; 141 pci_conf_read(dev, reg, (uint8_t *)&res, 2); 142 return res; 143 } 144 145 uint32_t pci_conf_read_32(device_t *dev, int reg) 146 { 147 uint32_t res; 148 pci_conf_read(dev, reg, (uint8_t *)&res, 4); 149 return res; 150 } 151 152 void pci_bus_scan(device_t *parent, int bus_num) 153 { 154 device_t *dev = create_device(); 155 pci_dev_data_t *dev_data = create_pci_dev_data(); 156 dev->driver_data = dev_data; 157 dev->parent = parent; 158 159 int child_bus = 0; 160 int dnum, fnum; 161 bool multi; 162 uint8_t header_type; 163 164 for (dnum = 0; dnum < 32; dnum++) { 165 multi = true; 166 for (fnum = 0; multi && fnum < 8; fnum++) { 167 init_pci_dev_data(dev_data, bus_num, dnum, fnum); 168 dev_data->vendor_id = pci_conf_read_16(dev, PCI_VENDOR_ID); 169 dev_data->device_id = pci_conf_read_16(dev, PCI_DEVICE_ID); 170 if (dev_data->vendor_id == 0xFFFF) { // device is not present, go on scanning the bus 171 if (fnum == 0) { 172 break; 173 } else { 174 continue; 175 } 176 } 177 header_type = pci_conf_read_8(dev, PCI_HEADER_TYPE); 178 if (fnum == 0) { 179 multi = header_type >> 7; // is the device multifunction? 180 } 181 header_type = header_type & 0x7F; // clear the multifunction bit 182 183 // TODO initialize device - name, match ids, interfaces 184 // TODO register device 185 186 if (header_type == PCI_HEADER_TYPE_BRIDGE || header_type == PCI_HEADER_TYPE_CARDBUS ) { 187 child_bus = pci_conf_read_8(dev, PCI_BRIDGE_SEC_BUS_NUM); 188 printf(NAME ": device is pci-to-pci bridge, secondary bus number = %d.\n", bus_num); 189 if(child_bus > bus_num) { 190 pci_bus_scan(parent, child_bus); 191 } 192 } 193 194 dev = create_device(); // alloc new aux. dev. structure 195 dev_data = create_pci_dev_data(); 196 dev->driver_data = dev_data; 197 dev->parent = parent; 198 } 199 } 200 201 if (dev_data->vendor_id == 0xFFFF) { 202 delete_device(dev); 203 delete_pci_dev_data(dev_data); // free the auxiliary device structure 204 } 205 206 } 79 207 80 208 static bool pci_add_device(device_t *dev) … … 82 210 printf(NAME ": pci_add_device\n"); 83 211 84 pci_bus_data_t *bus_data = (pci_bus_data_t *)malloc(sizeof(pci_bus_data_t));212 pci_bus_data_t *bus_data = create_pci_bus_data(); 85 213 if (NULL == bus_data) { 86 214 printf(NAME ": pci_add_device allocation failed.\n"); … … 125 253 126 254 // TODO scan the bus 255 pci_bus_scan(dev, 0); 127 256 128 257 clean_hw_resource_list(&hw_resources); -
uspace/srv/drivers/pciintel/pci.h
r8c06905 r5e598e0 36 36 #define PCI_H 37 37 38 39 #include <stdlib.h> 38 40 #include <driver.h> 41 #include <malloc.h> 39 42 40 43 typedef struct pci_dev_data { … … 42 45 int dev; 43 46 int fn; 44 hw_resource_list hw_resources; 47 int vendor_id; 48 int device_id; 49 hw_resource_list_t hw_resources; 45 50 } pci_dev_data_t; 46 51 52 static inline pci_dev_data_t *create_pci_dev_data() 53 { 54 pci_dev_data_t *res = (pci_dev_data_t *)malloc(sizeof(pci_dev_data_t)); 55 if (NULL != res) { 56 memset(res, 0, sizeof(pci_dev_data_t)); 57 } 58 return res; 59 } 47 60 61 static inline void init_pci_dev_data(pci_dev_data_t *d, int bus, int dev, int fn) 62 { 63 d->bus = bus; 64 d->dev = dev; 65 d->fn = fn; 66 } 67 68 static inline void delete_pci_dev_data(pci_dev_data_t *d) 69 { 70 if (NULL != d) { 71 clean_hw_resource_list(&d->hw_resources); 72 free(d); 73 } 74 } 75 76 uint8_t pci_conf_read_8(device_t *dev, int reg); 77 uint16_t pci_conf_read_16(device_t *dev, int reg); 78 uint32_t pci_conf_read_32(device_t *dev, int reg); 79 80 void pci_bus_scan(device_t *parent, int bus_num); 48 81 49 82 #endif
Note:
See TracChangeset
for help on using the changeset viewer.