mmc.cc
1 #include "version.h" 2 #include "hw.h" 3 #include "sysfs.h" 4 #include "osutils.h" 5 #include "mmc.h" 6 #include "disk.h" 7 #include "heuristics.h" 8 9 #include <vector> 10 #include <iostream> 11 12 __ID("@(#) $Id$"); 13 14 /* 15 * Standard SDIO Function Interfaces 16 */ 17 18 #define SDIO_CLASS_NONE 0x00 /* Not a SDIO standard interface */ 19 #define SDIO_CLASS_UART 0x01 /* standard UART interface */ 20 #define SDIO_CLASS_BT_A 0x02 /* Type-A BlueTooth std interface */ 21 #define SDIO_CLASS_BT_B 0x03 /* Type-B BlueTooth std interface */ 22 #define SDIO_CLASS_GPS 0x04 /* GPS standard interface */ 23 #define SDIO_CLASS_CAMERA 0x05 /* Camera standard interface */ 24 #define SDIO_CLASS_PHS 0x06 /* PHS standard interface */ 25 #define SDIO_CLASS_WLAN 0x07 /* WLAN interface */ 26 #define SDIO_CLASS_ATA 0x08 /* Embedded SDIO-ATA std interface */ 27 #define SDIO_CLASS_BT_AMP 0x09 /* Type-A Bluetooth AMP interface */ 28 29 /* 30 * Vendors and devices. Sort key: vendor first, device next. 31 */ 32 #define SDIO_VENDOR_ID_BROADCOM 0x02d0 33 #define SDIO_DEVICE_ID_BROADCOM_43143 0xa887 34 #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 35 #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 36 #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 37 #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 38 #define SDIO_DEVICE_ID_BROADCOM_43340 0xa94c 39 #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d 40 #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 41 #define SDIO_DEVICE_ID_BROADCOM_4339 0x4339 42 #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 43 #define SDIO_DEVICE_ID_BROADCOM_43364 0xa9a4 44 #define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6 45 #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 46 #define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf 47 #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 48 #define SDIO_DEVICE_ID_BROADCOM_4356 0x4356 49 #define SDIO_DEVICE_ID_BROADCOM_4359 0x4359 50 #define SDIO_DEVICE_ID_CYPRESS_4373 0x4373 51 #define SDIO_DEVICE_ID_CYPRESS_43012 43012 52 #define SDIO_DEVICE_ID_CYPRESS_89359 0x4355 53 54 #define SDIO_VENDOR_ID_INTEL 0x0089 55 #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 56 #define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI 0x1403 57 #define SDIO_DEVICE_ID_INTEL_IWMC3200TOP 0x1404 58 #define SDIO_DEVICE_ID_INTEL_IWMC3200GPS 0x1405 59 #define SDIO_DEVICE_ID_INTEL_IWMC3200BT 0x1406 60 #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5 0x1407 61 62 #define SDIO_VENDOR_ID_MARVELL 0x02df 63 #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 64 #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 65 #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 66 #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 67 #define SDIO_DEVICE_ID_MARVELL_8887WLAN 0x9134 68 69 #define SDIO_VENDOR_ID_MEDIATEK 0x037a 70 71 #define SDIO_VENDOR_ID_SIANO 0x039a 72 #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 73 #define SDIO_DEVICE_ID_SIANO_NICE 0x0202 74 #define SDIO_DEVICE_ID_SIANO_VEGA_A0 0x0300 75 #define SDIO_DEVICE_ID_SIANO_VENICE 0x0301 76 #define SDIO_DEVICE_ID_SIANO_NOVA_A0 0x1100 77 #define SDIO_DEVICE_ID_SIANO_STELLAR 0x5347 78 79 #define SDIO_VENDOR_ID_TI 0x0097 80 #define SDIO_DEVICE_ID_TI_WL1271 0x4076 81 #define SDIO_VENDOR_ID_TI_WL1251 0x104c 82 #define SDIO_DEVICE_ID_TI_WL1251 0x9066 83 84 #define SDIO_VENDOR_ID_STE 0x0020 85 #define SDIO_DEVICE_ID_STE_CW1200 0x2280 86 87 88 using namespace std; 89 90 static string strip0x(string s) 91 { 92 if(s.length()<2) return s; 93 if(s.substr(0, 2) == "0x") return s.substr(2, string::npos); 94 return s; 95 } 96 97 static string manufacturer(unsigned long n) 98 { 99 switch(n) 100 { 101 case 0x0: 102 return ""; 103 case 0x2: 104 return "Kingston"; 105 case 0x3: 106 return "SanDisk"; 107 default: 108 return "Unknown ("+tostring(n)+")"; 109 } 110 } 111 112 static hwNode sdioNode(unsigned long long c, unsigned long long vendor = 0, unsigned long long device = 0) 113 { 114 hwNode result("interface"); 115 116 switch(c) 117 { 118 case SDIO_CLASS_UART: 119 result = hwNode("serial", hw::communication); 120 result.setDescription("UART interface"); 121 break; 122 case SDIO_CLASS_BT_A: 123 case SDIO_CLASS_BT_B: 124 case SDIO_CLASS_BT_AMP: 125 result = hwNode("bt", hw::communication); 126 result.setDescription("BlueTooth interface"); 127 result.addCapability("wireless"); 128 result.addCapability("bluetooth"); 129 result.setConfig("wireless", "BlueTooth"); 130 break; 131 case SDIO_CLASS_GPS: 132 result = hwNode("gps"); 133 result.setDescription("GPS interface"); 134 break; 135 case SDIO_CLASS_CAMERA: 136 result = hwNode("camera"); 137 result.setDescription("Camera interface"); 138 break; 139 case SDIO_CLASS_PHS: 140 result = hwNode("phs"); 141 result.setDescription("PHS interface"); 142 break; 143 case SDIO_CLASS_WLAN: 144 result = hwNode("wifi", hw::network); 145 result.setDescription("Wireless interface"); 146 result.addCapability("wireless"); 147 result.setConfig("wireless", "IEEE 802.11"); 148 break; 149 case SDIO_CLASS_ATA: 150 result = hwNode("ata"); 151 result.setDescription("SDIO-ATA interface"); 152 break; 153 } 154 155 switch(vendor) 156 { 157 case SDIO_VENDOR_ID_BROADCOM: 158 result.setVendor("Broadcom"); 159 switch(device) 160 { 161 case SDIO_DEVICE_ID_BROADCOM_43143: 162 result.setProduct("43143"); 163 break; 164 case SDIO_DEVICE_ID_BROADCOM_43241: 165 result.setProduct("43241"); 166 break; 167 case SDIO_DEVICE_ID_BROADCOM_4329: 168 result.setProduct("4329"); 169 break; 170 case SDIO_DEVICE_ID_BROADCOM_4330: 171 result.setProduct("4330"); 172 break; 173 case SDIO_DEVICE_ID_BROADCOM_4334: 174 result.setProduct("4334"); 175 break; 176 case SDIO_DEVICE_ID_BROADCOM_43340: 177 result.setProduct("43340"); 178 break; 179 case SDIO_DEVICE_ID_BROADCOM_43341: 180 result.setProduct("43341"); 181 break; 182 case SDIO_DEVICE_ID_BROADCOM_4335_4339: 183 result.setProduct("4335/4339"); 184 break; 185 case SDIO_DEVICE_ID_BROADCOM_4339: 186 result.setProduct("4339"); 187 break; 188 case SDIO_DEVICE_ID_BROADCOM_43362: 189 result.setProduct("43362"); 190 break; 191 case SDIO_DEVICE_ID_BROADCOM_43364: 192 result.setProduct("43364"); 193 break; 194 case SDIO_DEVICE_ID_BROADCOM_43430: 195 result.setProduct("43430"); 196 break; 197 case SDIO_DEVICE_ID_BROADCOM_4345: 198 result.setProduct("4345"); 199 break; 200 case SDIO_DEVICE_ID_BROADCOM_43455: 201 result.setProduct("43455"); 202 break; 203 case SDIO_DEVICE_ID_BROADCOM_4354: 204 result.setProduct("4354"); 205 break; 206 case SDIO_DEVICE_ID_BROADCOM_4356: 207 result.setProduct("4356"); 208 break; 209 case SDIO_DEVICE_ID_BROADCOM_4359: 210 result.setProduct("4359"); 211 break; 212 case SDIO_DEVICE_ID_CYPRESS_4373: 213 result.setVendor("Cypress"); 214 result.setProduct("4373"); 215 break; 216 case SDIO_DEVICE_ID_CYPRESS_43012: 217 result.setVendor("Cypress"); 218 result.setProduct("43012"); 219 break; 220 case SDIO_DEVICE_ID_CYPRESS_89359: 221 result.setVendor("Cypress"); 222 result.setProduct("89359"); 223 break; 224 } 225 break; 226 case SDIO_VENDOR_ID_INTEL: 227 result.setVendor("Intel"); 228 switch(device) 229 { 230 case SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX: 231 result.setProduct("IWMC3200WIMAX"); 232 break; 233 case SDIO_DEVICE_ID_INTEL_IWMC3200WIFI: 234 result.setProduct("IWMC3200WIFI"); 235 break; 236 case SDIO_DEVICE_ID_INTEL_IWMC3200TOP: 237 result.setProduct("IWMC3200TOP"); 238 break; 239 case SDIO_DEVICE_ID_INTEL_IWMC3200GPS: 240 result.setProduct("IWMC3200GPS"); 241 break; 242 case SDIO_DEVICE_ID_INTEL_IWMC3200BT: 243 result.setProduct("IWMC3200BT"); 244 break; 245 case SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5: 246 result.setProduct("IWMC3200WIMAX 2G5"); 247 break; 248 } 249 break; 250 case SDIO_VENDOR_ID_MARVELL: 251 result.setVendor("Marvell"); 252 break; 253 case SDIO_VENDOR_ID_MEDIATEK: 254 result.setVendor("MediaTek"); 255 break; 256 case SDIO_VENDOR_ID_SIANO: 257 result.setVendor("Siano"); 258 switch(device) 259 { 260 case SDIO_DEVICE_ID_SIANO_NOVA_B0: 261 result.setProduct("NOVA B0"); 262 break; 263 case SDIO_DEVICE_ID_SIANO_NICE: 264 result.setProduct("NICE"); 265 break; 266 case SDIO_DEVICE_ID_SIANO_VEGA_A0: 267 result.setProduct("VEGA A0"); 268 break; 269 case SDIO_DEVICE_ID_SIANO_VENICE: 270 result.setProduct("VENICE"); 271 break; 272 case SDIO_DEVICE_ID_SIANO_NOVA_A0: 273 result.setProduct("NOVA A0"); 274 break; 275 case SDIO_DEVICE_ID_SIANO_STELLAR: 276 result.setProduct("STELLAR"); 277 break; 278 } 279 break; 280 case SDIO_VENDOR_ID_TI: 281 result.setVendor("Texas Instruments"); 282 switch(device) 283 { 284 case SDIO_DEVICE_ID_TI_WL1271: 285 result.setProduct("WL1271"); 286 break; 287 case SDIO_VENDOR_ID_TI_WL1251: 288 case SDIO_DEVICE_ID_TI_WL1251: 289 result.setProduct("WL1251"); 290 break; 291 } 292 break; 293 case SDIO_VENDOR_ID_STE: 294 result.setVendor("ST Ericsson"); 295 switch(device) 296 { 297 case SDIO_DEVICE_ID_STE_CW1200: 298 result.setProduct("CW1200"); 299 break; 300 } 301 break; 302 } 303 304 return result; 305 } 306 307 bool scan_mmc(hwNode & n) 308 { 309 vector < sysfs::entry > entries = sysfs::entries_by_class("mmc_host"); 310 311 if (entries.empty()) 312 return false; 313 314 for (vector < sysfs::entry >::iterator it = entries.begin(); 315 it != entries.end(); ++it) 316 { 317 const sysfs::entry & e = *it; 318 319 hwNode *device = n.findChildByBusInfo(e.leaf().businfo()); 320 if(!device) 321 device = n.addChild(hwNode(e.name(), hw::bus)); 322 else 323 device->setClass(hw::bus); 324 325 device->claim(); 326 device->setLogicalName(e.name()); 327 device->setDescription("MMC Host"); 328 device->setModalias(e.modalias()); 329 330 vector < sysfs::entry > devices = e.devices(); 331 for(vector < sysfs::entry >::iterator i = devices.begin(); i != devices.end(); ++i) 332 { 333 const sysfs::entry & d = *i; 334 335 hwNode card("device"); 336 card.claim(); 337 string prod = d.string_attr("name"); 338 if(prod != "00000") card.setProduct(prod); 339 card.addCapability(d.string_attr("type")); 340 card.setVendor(manufacturer(d.hex_attr("manfid"))); 341 card.setBusInfo(guessBusInfo(d.name())); 342 card.setPhysId(strip0x(d.string_attr("rca"))); 343 card.setSerial(tostring(d.hex_attr("serial"))); 344 if(unsigned long hwrev = d.hex_attr("hwrev")) { 345 card.setVersion(tostring(hwrev)+"."+tostring(d.hex_attr("fwrev"))); 346 } 347 card.setDate(d.string_attr("date")); 348 card.setDescription("SD/MMC Device"); 349 if(card.isCapable("sdio")) 350 card.setDescription("SDIO Device"); 351 if(d.string_attr("scr")!="") 352 { 353 card.setDescription("SD Card"); 354 card.setClass(hw::disk); 355 } 356 357 vector < sysfs::entry > devices = d.devices(); 358 for(unsigned long i=0;i<devices.size();i++) 359 { 360 hwNode *subdev; 361 if(devices.size()>1) 362 { 363 subdev = card.addChild(sdioNode(devices[i].hex_attr("class"), devices[i].hex_attr("vendor"), devices[i].hex_attr("device"))); 364 subdev->setPhysId(tostring(i+1)); 365 } 366 else 367 subdev = &card; 368 369 subdev->setLogicalName(devices[i].name()); 370 subdev->setModalias(devices[i].modalias()); 371 subdev->setBusInfo(guessBusInfo(devices[i].name())); 372 if(devices[i].hex_attr("removable")) 373 subdev->addCapability("removable"); 374 scan_disk(*subdev); 375 } 376 377 device->addChild(card); 378 } 379 380 } 381 382 return true; 383 }