Back to index

lshw  02.16
pcmcia-legacy.cc
Go to the documentation of this file.
00001 #include "version.h"
00002 #include "pcmcia-legacy.h"
00003 #include "osutils.h"
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <sys/ioctl.h>
00007 #include <fcntl.h>
00008 #include <unistd.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <errno.h>
00012 
00013 __ID("@(#) $Id: pcmcia-legacy.cc 2433 2012-01-10 22:01:30Z lyonel $");
00014 
00015 /* parts of this code come from the excellent pcmcia-cs package written by
00016  * David A. Hinds <dahinds@users.sourceforge.net>.
00017  */
00018 
00019 #define VARLIBPCMCIASTAB  "/var/lib/pcmcia/stab"
00020 
00021 #ifdef __arm__
00022 typedef u_int ioaddr_t;
00023 #else
00024 typedef u_short ioaddr_t;
00025 #endif
00026 
00027 typedef u_char cisdata_t;
00028 typedef u_int event_t;
00029 
00030 typedef struct cs_status_t
00031 {
00032   u_char Function;
00033   event_t CardState;
00034   event_t SocketState;
00035 }
00036 
00037 
00038 cs_status_t;
00039 
00040 #define CS_EVENT_CARD_DETECT            0x000080
00041 
00042 typedef struct config_info_t
00043 {
00044   u_char Function;
00045   u_int Attributes;
00046   u_int Vcc, Vpp1, Vpp2;
00047   u_int IntType;
00048   u_int ConfigBase;
00049   u_char Status, Pin, Copy, Option, ExtStatus;
00050   u_int Present;
00051   u_int CardValues;
00052   u_int AssignedIRQ;
00053   u_int IRQAttributes;
00054   ioaddr_t BasePort1;
00055   ioaddr_t NumPorts1;
00056   u_int Attributes1;
00057   ioaddr_t BasePort2;
00058   ioaddr_t NumPorts2;
00059   u_int Attributes2;
00060   u_int IOAddrLines;
00061 }
00062 
00063 
00064 config_info_t;
00065 
00066 #define DEV_NAME_LEN 32
00067 typedef char dev_info_t[DEV_NAME_LEN];
00068 
00069 typedef struct bind_info_t
00070 {
00071   dev_info_t dev_info;
00072   u_char function;
00073 /*
00074  * struct dev_link_t   *instance;
00075  */
00076   void *instance;
00077   char name[DEV_NAME_LEN];
00078   u_short major, minor;
00079   void *next;
00080 }
00081 
00082 
00083 bind_info_t;
00084 
00085 #define BIND_FN_ALL 0xff
00086 
00087 #define CISTPL_NULL   0x00
00088 #define CISTPL_DEVICE   0x01
00089 #define CISTPL_LONGLINK_CB  0x02
00090 #define CISTPL_INDIRECT   0x03
00091 #define CISTPL_CONFIG_CB  0x04
00092 #define CISTPL_CFTABLE_ENTRY_CB 0x05
00093 #define CISTPL_LONGLINK_MFC 0x06
00094 #define CISTPL_BAR    0x07
00095 #define CISTPL_PWR_MGMNT  0x08
00096 #define CISTPL_EXTDEVICE  0x09
00097 #define CISTPL_CHECKSUM   0x10
00098 #define CISTPL_LONGLINK_A 0x11
00099 #define CISTPL_LONGLINK_C 0x12
00100 #define CISTPL_LINKTARGET 0x13
00101 #define CISTPL_NO_LINK    0x14
00102 #define CISTPL_VERS_1   0x15
00103 #define CISTPL_ALTSTR   0x16
00104 #define CISTPL_DEVICE_A   0x17
00105 #define CISTPL_JEDEC_C    0x18
00106 #define CISTPL_JEDEC_A    0x19
00107 #define CISTPL_CONFIG   0x1a
00108 #define CISTPL_CFTABLE_ENTRY  0x1b
00109 #define CISTPL_DEVICE_OC  0x1c
00110 #define CISTPL_DEVICE_OA  0x1d
00111 #define CISTPL_DEVICE_GEO 0x1e
00112 #define CISTPL_DEVICE_GEO_A 0x1f
00113 #define CISTPL_MANFID   0x20
00114 #define CISTPL_FUNCID   0x21
00115 #define CISTPL_FUNCE    0x22
00116 #define CISTPL_SWIL   0x23
00117 #define CISTPL_END    0xff
00118 /* Layer 2 tuples */
00119 #define CISTPL_VERS_2   0x40
00120 #define CISTPL_FORMAT   0x41
00121 #define CISTPL_GEOMETRY   0x42
00122 #define CISTPL_BYTEORDER  0x43
00123 #define CISTPL_DATE   0x44
00124 #define CISTPL_BATTERY    0x45
00125 #define CISTPL_FORMAT_A   0x47
00126 /* Layer 3 tuples */
00127 #define CISTPL_ORG    0x46
00128 #define CISTPL_SPCL   0x90
00129 
00130 typedef struct cistpl_longlink_t
00131 {
00132   u_int addr;
00133 }
00134 
00135 
00136 cistpl_longlink_t;
00137 
00138 typedef struct cistpl_checksum_t
00139 {
00140   u_short addr;
00141   u_short len;
00142   u_char sum;
00143 }
00144 
00145 
00146 cistpl_checksum_t;
00147 
00148 #define CISTPL_MAX_FUNCTIONS  8
00149 #define CISTPL_MFC_ATTR   0x00
00150 #define CISTPL_MFC_COMMON 0x01
00151 
00152 typedef struct cistpl_longlink_mfc_t
00153 {
00154   u_char nfn;
00155   struct
00156   {
00157     u_char space;
00158     u_int addr;
00159   }
00160   fn[CISTPL_MAX_FUNCTIONS];
00161 }
00162 
00163 
00164 cistpl_longlink_mfc_t;
00165 
00166 #define CISTPL_MAX_ALTSTR_STRINGS 4
00167 
00168 typedef struct cistpl_altstr_t
00169 {
00170   u_char ns;
00171   u_char ofs[CISTPL_MAX_ALTSTR_STRINGS];
00172   char str[254];
00173 }
00174 
00175 
00176 cistpl_altstr_t;
00177 
00178 #define CISTPL_DTYPE_NULL 0x00
00179 #define CISTPL_DTYPE_ROM  0x01
00180 #define CISTPL_DTYPE_OTPROM 0x02
00181 #define CISTPL_DTYPE_EPROM  0x03
00182 #define CISTPL_DTYPE_EEPROM 0x04
00183 #define CISTPL_DTYPE_FLASH  0x05
00184 #define CISTPL_DTYPE_SRAM 0x06
00185 #define CISTPL_DTYPE_DRAM 0x07
00186 #define CISTPL_DTYPE_FUNCSPEC 0x0d
00187 #define CISTPL_DTYPE_EXTEND 0x0e
00188 
00189 #define CISTPL_MAX_DEVICES  4
00190 
00191 typedef struct cistpl_device_t
00192 {
00193   u_char ndev;
00194   struct
00195   {
00196     u_char type;
00197     u_char wp;
00198     u_int speed;
00199     u_int size;
00200   }
00201   dev[CISTPL_MAX_DEVICES];
00202 }
00203 
00204 
00205 cistpl_device_t;
00206 
00207 #define CISTPL_DEVICE_MWAIT 0x01
00208 #define CISTPL_DEVICE_3VCC  0x02
00209 
00210 typedef struct cistpl_device_o_t
00211 {
00212   u_char flags;
00213   cistpl_device_t device;
00214 }
00215 
00216 
00217 cistpl_device_o_t;
00218 
00219 #define CISTPL_VERS_1_MAX_PROD_STRINGS  4
00220 
00221 typedef struct cistpl_vers_1_t
00222 {
00223   u_char major;
00224   u_char minor;
00225   u_char ns;
00226   u_char ofs[CISTPL_VERS_1_MAX_PROD_STRINGS];
00227   char str[254];
00228 }
00229 
00230 
00231 cistpl_vers_1_t;
00232 
00233 typedef struct cistpl_jedec_t
00234 {
00235   u_char nid;
00236   struct
00237   {
00238     u_char mfr;
00239     u_char info;
00240   }
00241   id[CISTPL_MAX_DEVICES];
00242 }
00243 
00244 
00245 cistpl_jedec_t;
00246 
00247 typedef struct cistpl_manfid_t
00248 {
00249   u_short manf;
00250   u_short card;
00251 }
00252 
00253 
00254 cistpl_manfid_t;
00255 
00256 #define CISTPL_FUNCID_MULTI 0x00
00257 #define CISTPL_FUNCID_MEMORY  0x01
00258 #define CISTPL_FUNCID_SERIAL  0x02
00259 #define CISTPL_FUNCID_PARALLEL  0x03
00260 #define CISTPL_FUNCID_FIXED 0x04
00261 #define CISTPL_FUNCID_VIDEO 0x05
00262 #define CISTPL_FUNCID_NETWORK 0x06
00263 #define CISTPL_FUNCID_AIMS  0x07
00264 #define CISTPL_FUNCID_SCSI  0x08
00265 
00266 #define CISTPL_SYSINIT_POST 0x01
00267 #define CISTPL_SYSINIT_ROM  0x02
00268 
00269 typedef struct cistpl_funcid_t
00270 {
00271   u_char func;
00272   u_char sysinit;
00273 }
00274 
00275 
00276 cistpl_funcid_t;
00277 
00278 typedef struct cistpl_funce_t
00279 {
00280   u_char type;
00281   u_char data[0];
00282 }
00283 
00284 
00285 cistpl_funce_t;
00286 
00287 /*======================================================================
00288 
00289     Modem Function Extension Tuples
00290 
00291 ======================================================================*/
00292 
00293 #define CISTPL_FUNCE_SERIAL_IF    0x00
00294 #define CISTPL_FUNCE_SERIAL_CAP   0x01
00295 #define CISTPL_FUNCE_SERIAL_SERV_DATA 0x02
00296 #define CISTPL_FUNCE_SERIAL_SERV_FAX  0x03
00297 #define CISTPL_FUNCE_SERIAL_SERV_VOICE  0x04
00298 #define CISTPL_FUNCE_SERIAL_CAP_DATA  0x05
00299 #define CISTPL_FUNCE_SERIAL_CAP_FAX 0x06
00300 #define CISTPL_FUNCE_SERIAL_CAP_VOICE 0x07
00301 #define CISTPL_FUNCE_SERIAL_IF_DATA 0x08
00302 #define CISTPL_FUNCE_SERIAL_IF_FAX  0x09
00303 #define CISTPL_FUNCE_SERIAL_IF_VOICE  0x0a
00304 
00305 /* UART identification */
00306 #define CISTPL_SERIAL_UART_8250   0x00
00307 #define CISTPL_SERIAL_UART_16450  0x01
00308 #define CISTPL_SERIAL_UART_16550  0x02
00309 #define CISTPL_SERIAL_UART_8251   0x03
00310 #define CISTPL_SERIAL_UART_8530   0x04
00311 #define CISTPL_SERIAL_UART_85230  0x05
00312 
00313 /* UART capabilities */
00314 #define CISTPL_SERIAL_UART_SPACE  0x01
00315 #define CISTPL_SERIAL_UART_MARK   0x02
00316 #define CISTPL_SERIAL_UART_ODD    0x04
00317 #define CISTPL_SERIAL_UART_EVEN   0x08
00318 #define CISTPL_SERIAL_UART_5BIT   0x01
00319 #define CISTPL_SERIAL_UART_6BIT   0x02
00320 #define CISTPL_SERIAL_UART_7BIT   0x04
00321 #define CISTPL_SERIAL_UART_8BIT   0x08
00322 #define CISTPL_SERIAL_UART_1STOP  0x10
00323 #define CISTPL_SERIAL_UART_MSTOP  0x20
00324 #define CISTPL_SERIAL_UART_2STOP  0x40
00325 
00326 typedef struct cistpl_serial_t
00327 {
00328   u_char uart_type;
00329   u_char uart_cap_0;
00330   u_char uart_cap_1;
00331 }
00332 
00333 
00334 cistpl_serial_t;
00335 
00336 typedef struct cistpl_modem_cap_t
00337 {
00338   u_char flow;
00339   u_char cmd_buf;
00340   u_char rcv_buf_0, rcv_buf_1, rcv_buf_2;
00341   u_char xmit_buf_0, xmit_buf_1, xmit_buf_2;
00342 }
00343 
00344 
00345 cistpl_modem_cap_t;
00346 
00347 #define CISTPL_SERIAL_MOD_103   0x01
00348 #define CISTPL_SERIAL_MOD_V21   0x02
00349 #define CISTPL_SERIAL_MOD_V23   0x04
00350 #define CISTPL_SERIAL_MOD_V22   0x08
00351 #define CISTPL_SERIAL_MOD_212A    0x10
00352 #define CISTPL_SERIAL_MOD_V22BIS  0x20
00353 #define CISTPL_SERIAL_MOD_V26   0x40
00354 #define CISTPL_SERIAL_MOD_V26BIS  0x80
00355 #define CISTPL_SERIAL_MOD_V27BIS  0x01
00356 #define CISTPL_SERIAL_MOD_V29   0x02
00357 #define CISTPL_SERIAL_MOD_V32   0x04
00358 #define CISTPL_SERIAL_MOD_V32BIS  0x08
00359 #define CISTPL_SERIAL_MOD_V34   0x10
00360 
00361 #define CISTPL_SERIAL_ERR_MNP2_4  0x01
00362 #define CISTPL_SERIAL_ERR_V42_LAPM  0x02
00363 
00364 #define CISTPL_SERIAL_CMPR_V42BIS 0x01
00365 #define CISTPL_SERIAL_CMPR_MNP5   0x02
00366 
00367 #define CISTPL_SERIAL_CMD_AT1   0x01
00368 #define CISTPL_SERIAL_CMD_AT2   0x02
00369 #define CISTPL_SERIAL_CMD_AT3   0x04
00370 #define CISTPL_SERIAL_CMD_MNP_AT  0x08
00371 #define CISTPL_SERIAL_CMD_V25BIS  0x10
00372 #define CISTPL_SERIAL_CMD_V25A    0x20
00373 #define CISTPL_SERIAL_CMD_DMCL    0x40
00374 
00375 typedef struct cistpl_data_serv_t
00376 {
00377   u_char max_data_0;
00378   u_char max_data_1;
00379   u_char modulation_0;
00380   u_char modulation_1;
00381   u_char error_control;
00382   u_char compression;
00383   u_char cmd_protocol;
00384   u_char escape;
00385   u_char encrypt;
00386   u_char misc_features;
00387   u_char ccitt_code[0];
00388 }
00389 
00390 
00391 cistpl_data_serv_t;
00392 
00393 typedef struct cistpl_fax_serv_t
00394 {
00395   u_char max_data_0;
00396   u_char max_data_1;
00397   u_char modulation;
00398   u_char encrypt;
00399   u_char features_0;
00400   u_char features_1;
00401   u_char ccitt_code[0];
00402 }
00403 
00404 
00405 cistpl_fax_serv_t;
00406 
00407 typedef struct cistpl_voice_serv_t
00408 {
00409   u_char max_data_0;
00410   u_char max_data_1;
00411 }
00412 
00413 
00414 cistpl_voice_serv_t;
00415 
00416 /*======================================================================
00417 
00418     LAN Function Extension Tuples
00419 
00420 ======================================================================*/
00421 
00422 #define CISTPL_FUNCE_LAN_TECH   0x01
00423 #define CISTPL_FUNCE_LAN_SPEED    0x02
00424 #define CISTPL_FUNCE_LAN_MEDIA    0x03
00425 #define CISTPL_FUNCE_LAN_NODE_ID  0x04
00426 #define CISTPL_FUNCE_LAN_CONNECTOR  0x05
00427 
00428 /* LAN technologies */
00429 #define CISTPL_LAN_TECH_ARCNET    0x01
00430 #define CISTPL_LAN_TECH_ETHERNET  0x02
00431 #define CISTPL_LAN_TECH_TOKENRING 0x03
00432 #define CISTPL_LAN_TECH_LOCALTALK 0x04
00433 #define CISTPL_LAN_TECH_FDDI    0x05
00434 #define CISTPL_LAN_TECH_ATM   0x06
00435 #define CISTPL_LAN_TECH_WIRELESS  0x07
00436 
00437 typedef struct cistpl_lan_tech_t
00438 {
00439   u_char tech;
00440 }
00441 
00442 
00443 cistpl_lan_tech_t;
00444 
00445 typedef struct cistpl_lan_speed_t
00446 {
00447   u_int speed;
00448 }
00449 
00450 
00451 cistpl_lan_speed_t;
00452 
00453 /* LAN media definitions */
00454 #define CISTPL_LAN_MEDIA_UTP    0x01
00455 #define CISTPL_LAN_MEDIA_STP    0x02
00456 #define CISTPL_LAN_MEDIA_THIN_COAX  0x03
00457 #define CISTPL_LAN_MEDIA_THICK_COAX 0x04
00458 #define CISTPL_LAN_MEDIA_FIBER    0x05
00459 #define CISTPL_LAN_MEDIA_900MHZ   0x06
00460 #define CISTPL_LAN_MEDIA_2GHZ   0x07
00461 #define CISTPL_LAN_MEDIA_5GHZ   0x08
00462 #define CISTPL_LAN_MEDIA_DIFF_IR  0x09
00463 #define CISTPL_LAN_MEDIA_PTP_IR   0x0a
00464 
00465 typedef struct cistpl_lan_media_t
00466 {
00467   u_char media;
00468 }
00469 
00470 
00471 cistpl_lan_media_t;
00472 
00473 typedef struct cistpl_lan_node_id_t
00474 {
00475   u_char nb;
00476   u_char id[16];
00477 }
00478 
00479 
00480 cistpl_lan_node_id_t;
00481 
00482 typedef struct cistpl_lan_connector_t
00483 {
00484   u_char code;
00485 }
00486 
00487 
00488 cistpl_lan_connector_t;
00489 
00490 /*======================================================================
00491 
00492     IDE Function Extension Tuples
00493 
00494 ======================================================================*/
00495 
00496 #define CISTPL_IDE_INTERFACE    0x01
00497 
00498 typedef struct cistpl_ide_interface_t
00499 {
00500   u_char interface;
00501 }
00502 
00503 
00504 cistpl_ide_interface_t;
00505 
00506 /* First feature byte */
00507 #define CISTPL_IDE_SILICON    0x04
00508 #define CISTPL_IDE_UNIQUE   0x08
00509 #define CISTPL_IDE_DUAL     0x10
00510 
00511 /* Second feature byte */
00512 #define CISTPL_IDE_HAS_SLEEP    0x01
00513 #define CISTPL_IDE_HAS_STANDBY    0x02
00514 #define CISTPL_IDE_HAS_IDLE   0x04
00515 #define CISTPL_IDE_LOW_POWER    0x08
00516 #define CISTPL_IDE_REG_INHIBIT    0x10
00517 #define CISTPL_IDE_HAS_INDEX    0x20
00518 #define CISTPL_IDE_IOIS16   0x40
00519 
00520 typedef struct cistpl_ide_feature_t
00521 {
00522   u_char feature1;
00523   u_char feature2;
00524 }
00525 
00526 
00527 cistpl_ide_feature_t;
00528 
00529 #define CISTPL_FUNCE_IDE_IFACE    0x01
00530 #define CISTPL_FUNCE_IDE_MASTER   0x02
00531 #define CISTPL_FUNCE_IDE_SLAVE    0x03
00532 
00533 /*======================================================================
00534 
00535     Configuration Table Entries
00536 
00537 ======================================================================*/
00538 
00539 #define CISTPL_BAR_SPACE  0x07
00540 #define CISTPL_BAR_SPACE_IO 0x10
00541 #define CISTPL_BAR_PREFETCH 0x20
00542 #define CISTPL_BAR_CACHEABLE  0x40
00543 #define CISTPL_BAR_1MEG_MAP 0x80
00544 
00545 typedef struct cistpl_bar_t
00546 {
00547   u_char attr;
00548   u_int size;
00549 }
00550 
00551 
00552 cistpl_bar_t;
00553 
00554 typedef struct cistpl_config_t
00555 {
00556   u_char last_idx;
00557   u_int base;
00558   u_int rmask[4];
00559   u_char subtuples;
00560 }
00561 
00562 
00563 cistpl_config_t;
00564 
00565 /* These are bits in the 'present' field, and indices in 'param' */
00566 #define CISTPL_POWER_VNOM 0
00567 #define CISTPL_POWER_VMIN 1
00568 #define CISTPL_POWER_VMAX 2
00569 #define CISTPL_POWER_ISTATIC  3
00570 #define CISTPL_POWER_IAVG 4
00571 #define CISTPL_POWER_IPEAK  5
00572 #define CISTPL_POWER_IDOWN  6
00573 
00574 #define CISTPL_POWER_HIGHZ_OK 0x01
00575 #define CISTPL_POWER_HIGHZ_REQ  0x02
00576 
00577 typedef struct cistpl_power_t
00578 {
00579   u_char present;
00580   u_char flags;
00581   u_int param[7];
00582 }
00583 
00584 
00585 cistpl_power_t;
00586 
00587 typedef struct cistpl_timing_t
00588 {
00589   u_int wait, waitscale;
00590   u_int ready, rdyscale;
00591   u_int reserved, rsvscale;
00592 }
00593 
00594 
00595 cistpl_timing_t;
00596 
00597 #define CISTPL_IO_LINES_MASK  0x1f
00598 #define CISTPL_IO_8BIT    0x20
00599 #define CISTPL_IO_16BIT   0x40
00600 #define CISTPL_IO_RANGE   0x80
00601 
00602 #define CISTPL_IO_MAX_WIN 16
00603 
00604 typedef struct cistpl_io_t
00605 {
00606   u_char flags;
00607   u_char nwin;
00608   struct
00609   {
00610     u_int base;
00611     u_int len;
00612   }
00613   win[CISTPL_IO_MAX_WIN];
00614 }
00615 
00616 
00617 cistpl_io_t;
00618 
00619 typedef struct cistpl_irq_t
00620 {
00621   u_int IRQInfo1;
00622   u_int IRQInfo2;
00623 }
00624 
00625 
00626 cistpl_irq_t;
00627 
00628 #define CISTPL_MEM_MAX_WIN  8
00629 
00630 typedef struct cistpl_mem_t
00631 {
00632   u_char flags;
00633   u_char nwin;
00634   struct
00635   {
00636     u_int len;
00637     u_int card_addr;
00638     u_int host_addr;
00639   }
00640   win[CISTPL_MEM_MAX_WIN];
00641 }
00642 
00643 
00644 cistpl_mem_t;
00645 
00646 #define CISTPL_CFTABLE_DEFAULT    0x0001
00647 #define CISTPL_CFTABLE_BVDS   0x0002
00648 #define CISTPL_CFTABLE_WP   0x0004
00649 #define CISTPL_CFTABLE_RDYBSY   0x0008
00650 #define CISTPL_CFTABLE_MWAIT    0x0010
00651 #define CISTPL_CFTABLE_AUDIO    0x0800
00652 #define CISTPL_CFTABLE_READONLY   0x1000
00653 #define CISTPL_CFTABLE_PWRDOWN    0x2000
00654 
00655 typedef struct cistpl_cftable_entry_t
00656 {
00657   u_char index;
00658   u_short flags;
00659   u_char interface;
00660   cistpl_power_t vcc, vpp1, vpp2;
00661   cistpl_timing_t timing;
00662   cistpl_io_t io;
00663   cistpl_irq_t irq;
00664   cistpl_mem_t mem;
00665   u_char subtuples;
00666 }
00667 
00668 
00669 cistpl_cftable_entry_t;
00670 
00671 #define CISTPL_CFTABLE_MASTER   0x000100
00672 #define CISTPL_CFTABLE_INVALIDATE 0x000200
00673 #define CISTPL_CFTABLE_VGA_PALETTE  0x000400
00674 #define CISTPL_CFTABLE_PARITY   0x000800
00675 #define CISTPL_CFTABLE_WAIT   0x001000
00676 #define CISTPL_CFTABLE_SERR   0x002000
00677 #define CISTPL_CFTABLE_FAST_BACK  0x004000
00678 #define CISTPL_CFTABLE_BINARY_AUDIO 0x010000
00679 #define CISTPL_CFTABLE_PWM_AUDIO  0x020000
00680 
00681 typedef struct cistpl_cftable_entry_cb_t
00682 {
00683   u_char index;
00684   u_int flags;
00685   cistpl_power_t vcc, vpp1, vpp2;
00686   u_char io;
00687   cistpl_irq_t irq;
00688   u_char mem;
00689   u_char subtuples;
00690 }
00691 
00692 
00693 cistpl_cftable_entry_cb_t;
00694 
00695 typedef struct cistpl_device_geo_t
00696 {
00697   u_char ngeo;
00698   struct
00699   {
00700     u_char buswidth;
00701     u_int erase_block;
00702     u_int read_block;
00703     u_int write_block;
00704     u_int partition;
00705     u_int interleave;
00706   }
00707   geo[CISTPL_MAX_DEVICES];
00708 }
00709 
00710 
00711 cistpl_device_geo_t;
00712 
00713 typedef struct cistpl_vers_2_t
00714 {
00715   u_char vers;
00716   u_char comply;
00717   u_short dindex;
00718   u_char vspec8, vspec9;
00719   u_char nhdr;
00720   u_char vendor, info;
00721   char str[244];
00722 }
00723 
00724 
00725 cistpl_vers_2_t;
00726 
00727 typedef struct cistpl_org_t
00728 {
00729   u_char data_org;
00730   char desc[30];
00731 }
00732 
00733 
00734 cistpl_org_t;
00735 
00736 #define CISTPL_ORG_FS   0x00
00737 #define CISTPL_ORG_APPSPEC  0x01
00738 #define CISTPL_ORG_XIP    0x02
00739 
00740 typedef struct cistpl_format_t
00741 {
00742   u_char type;
00743   u_char edc;
00744   u_int offset;
00745   u_int length;
00746 }
00747 
00748 
00749 cistpl_format_t;
00750 
00751 #define CISTPL_FORMAT_DISK  0x00
00752 #define CISTPL_FORMAT_MEM 0x01
00753 
00754 #define CISTPL_EDC_NONE   0x00
00755 #define CISTPL_EDC_CKSUM  0x01
00756 #define CISTPL_EDC_CRC    0x02
00757 #define CISTPL_EDC_PCC    0x03
00758 
00759 typedef union cisparse_t
00760 {
00761   cistpl_device_t device;
00762   cistpl_checksum_t checksum;
00763   cistpl_longlink_t longlink;
00764   cistpl_longlink_mfc_t longlink_mfc;
00765   cistpl_vers_1_t version_1;
00766   cistpl_altstr_t altstr;
00767   cistpl_jedec_t jedec;
00768   cistpl_manfid_t manfid;
00769   cistpl_funcid_t funcid;
00770   cistpl_funce_t funce;
00771   cistpl_bar_t bar;
00772   cistpl_config_t config;
00773   cistpl_cftable_entry_t cftable_entry;
00774   cistpl_cftable_entry_cb_t cftable_entry_cb;
00775   cistpl_device_geo_t device_geo;
00776   cistpl_vers_2_t vers_2;
00777   cistpl_org_t org;
00778   cistpl_format_t format;
00779 }
00780 
00781 
00782 cisparse_t;
00783 
00784 typedef struct tuple_t
00785 {
00786   u_int Attributes;
00787   cisdata_t DesiredTuple;
00788   u_int Flags;                                    /* internal use */
00789   u_int LinkOffset;                               /* internal use */
00790   u_int CISOffset;                                /* internal use */
00791   cisdata_t TupleCode;
00792   cisdata_t TupleLink;
00793   cisdata_t TupleOffset;
00794   cisdata_t TupleDataMax;
00795   cisdata_t TupleDataLen;
00796   cisdata_t *TupleData;
00797 }
00798 
00799 
00800 tuple_t;
00801 
00802 typedef struct tuple_parse_t
00803 {
00804   tuple_t tuple;
00805   cisdata_t data[255];
00806   cisparse_t parse;
00807 }
00808 
00809 
00810 tuple_parse_t;
00811 
00812 typedef union ds_ioctl_arg_t
00813 {
00814 //servinfo_t servinfo;
00815 //adjust_t            adjust;
00816   config_info_t config;
00817   tuple_t tuple;
00818   tuple_parse_t tuple_parse;
00819 //client_req_t        client_req;
00820 //cs_status_t         status;
00821 //conf_reg_t          conf_reg;
00822 //cisinfo_t           cisinfo;
00823 //region_info_t       region;
00824   bind_info_t bind_info;
00825 //mtd_info_t          mtd_info;
00826 //win_info_t          win_info;
00827 //cisdump_t           cisdump;
00828 }
00829 
00830 
00831 ds_ioctl_arg_t;
00832 
00833 #define TUPLE_RETURN_COMMON             0x02
00834 #define DS_GET_CARD_SERVICES_INFO       _IOR ('d', 1, servinfo_t)
00835 #define DS_GET_CONFIGURATION_INFO       _IOWR('d', 3, config_info_t)
00836 #define DS_GET_FIRST_TUPLE              _IOWR('d', 4, tuple_t)
00837 #define DS_GET_NEXT_TUPLE               _IOWR('d', 5, tuple_t)
00838 #define DS_GET_TUPLE_DATA               _IOWR('d', 6, tuple_parse_t)
00839 #define DS_PARSE_TUPLE                  _IOWR('d', 7, tuple_parse_t)
00840 #define DS_GET_STATUS                   _IOWR('d', 9, cs_status_t)
00841 #define DS_BIND_REQUEST                 _IOWR('d', 60, bind_info_t)
00842 #define DS_GET_DEVICE_INFO              _IOWR('d', 61, bind_info_t)
00843 #define DS_GET_NEXT_DEVICE              _IOWR('d', 62, bind_info_t)
00844 
00845 #define MAX_SOCK 8
00846 
00847 static int lookup_dev(const char *name)
00848 {
00849   FILE *f;
00850   int n;
00851   char s[32], t[32];
00852 
00853   f = fopen("/proc/devices", "r");
00854   if (f == NULL)
00855     return -errno;
00856   while (fgets(s, 32, f) != NULL)
00857   {
00858     if (sscanf(s, "%d %s", &n, t) == 2)
00859       if (strcmp(name, t) == 0)
00860         break;
00861   }
00862   fclose(f);
00863   if (strcmp(name, t) == 0)
00864     return n;
00865   else
00866     return -ENODEV;
00867 }                                                 /* lookup_dev */
00868 
00869 
00870 static string pcmcia_handle(int socket)
00871 {
00872   char buffer[20];
00873 
00874   snprintf(buffer, sizeof(buffer), "PCMCIA:%d", socket);
00875 
00876   return string(buffer);
00877 }
00878 
00879 
00880 static int get_tuple(int fd,
00881 cisdata_t code,
00882 ds_ioctl_arg_t & arg)
00883 {
00884   arg.tuple.DesiredTuple = code;
00885   arg.tuple.Attributes = TUPLE_RETURN_COMMON;
00886   arg.tuple.TupleOffset = 0;
00887   if ((ioctl(fd, DS_GET_FIRST_TUPLE, &arg) == 0) &&
00888     (ioctl(fd, DS_GET_TUPLE_DATA, &arg) == 0) &&
00889     (ioctl(fd, DS_PARSE_TUPLE, &arg) == 0))
00890     return 0;
00891   else
00892     return -1;
00893 }
00894 
00895 
00896 static bool pcmcia_ident(int socket,
00897 int fd,
00898 hwNode * parent)
00899 {
00900   ds_ioctl_arg_t arg;
00901   cistpl_vers_1_t *vers = &arg.tuple_parse.parse.version_1;
00902   cistpl_funcid_t *funcid = &arg.tuple_parse.parse.funcid;
00903   config_info_t config;
00904   vector < string > product_info;
00905   hwNode device("pccard",
00906     hw::generic);
00907   char buffer[20];
00908   int i;
00909 
00910   if (get_tuple(fd, CISTPL_VERS_1, arg) == 0)
00911     for (i = 0; i < vers->ns; i++)
00912   {
00913     product_info.push_back(string(vers->str + vers->ofs[i]));
00914   }
00915   else
00916     return false;
00917 
00918   if (get_tuple(fd, CISTPL_FUNCID, arg) == 0)
00919     switch (funcid->func)
00920     {
00921       case 0:                                     // multifunction
00922         break;
00923       case 1:                                     // memory
00924         device = hwNode("memory", hw::memory);
00925         device.claim();
00926         break;
00927       case 2:                                     // serial
00928         device = hwNode("serial", hw::communication);
00929         device.claim();
00930       break;
00931     case 3:                                       // parallel
00932       device = hwNode("parallel", hw::communication);
00933       device.claim();
00934       break;
00935     case 4:                                       // fixed disk
00936       device = hwNode("storage", hw::storage);
00937       device.claim();
00938       break;
00939     case 5:                                       // video
00940       device = hwNode("video", hw::display);
00941       device.claim();
00942       break;
00943     case 6:                                       // network
00944       device = hwNode("network", hw::network);
00945       device.claim();
00946       break;
00947     case 7:                                       // AIMS ?
00948       break;
00949     case 8:                                       // SCSI
00950       device = hwNode("scsi", hw::bus);
00951       device.claim();
00952       break;
00953     default:
00954       break;
00955   }
00956 
00957   if (product_info.size() >= 2)
00958   {
00959     if (product_info.size() >= 3)
00960     {
00961       device.setVendor(product_info[0]);
00962       if (product_info.size() >= 4)
00963       {
00964         device.setDescription(product_info[1]);
00965         device.setProduct(product_info[2]);
00966       }
00967       else
00968         device.setDescription(product_info[1]);
00969     }
00970     else
00971       device.setDescription(product_info[0]);
00972     device.setVersion(product_info[product_info.size() - 1]);
00973   }
00974   else
00975   {
00976     if (product_info.size() >= 1)
00977       device.setDescription(product_info[0]);
00978   }
00979 
00980   snprintf(buffer, sizeof(buffer), "Socket %d", socket);
00981   device.setSlot(buffer);
00982 
00983   for (int fct = 0; fct < 4; fct++)
00984   {
00985     memset(&config, 0, sizeof(config));
00986     config.Function = fct;
00987     if (ioctl(fd, DS_GET_CONFIGURATION_INFO, &config) == 0)
00988     {
00989       if (config.AssignedIRQ != 0)
00990         device.addResource(hw::resource::irq(config.AssignedIRQ));
00991     }
00992   }
00993 
00994 //memset(&bind, 0, sizeof(bind));
00995 //strcpy(bind.dev_info, "cb_enabler");
00996 //bind.function = 0;
00997 //ioctl(fd, DS_GET_NEXT_DEVICE, &bind);
00998 //printf("%s : %s -> %d\n", bind.dev_info, bind.name, errno);
00999 
01000   device.setHandle(pcmcia_handle(socket));
01001   parent->addChild(device);
01002 
01003   return true;
01004 }
01005 
01006 
01007 static bool is_cardbus(const hwNode * n)
01008 {
01009   return (n->getClass() == hw::bridge) && n->isCapable("pcmcia");
01010 }
01011 
01012 
01013 static hwNode *find_pcmciaparent(int slot,
01014 hwNode & root)
01015 {
01016   hwNode *result = NULL;
01017   unsigned int i;
01018   int currentslot = 0;
01019 
01020   if (slot < 0)
01021     return NULL;
01022 
01023   result = root.findChildByHandle(pcmcia_handle(slot));
01024   if (result)
01025     return result;
01026 
01027   for (i = 0; i < root.countChildren(); i++)
01028   {
01029     if (is_cardbus(root.getChild(i)))
01030     {
01031       if (currentslot == slot)
01032         return (hwNode *) root.getChild(i);
01033       currentslot++;
01034     }
01035   }
01036 
01037   for (i = 0; i < root.countChildren(); i++)
01038   {
01039     result = NULL;
01040     result =
01041       find_pcmciaparent(slot - currentslot, *(hwNode *) root.getChild(i));
01042     if (result)
01043       return result;
01044   }
01045 
01046   return NULL;
01047 }
01048 
01049 
01050 bool scan_pcmcialegacy(hwNode & n)
01051 {
01052   int fd[MAX_SOCK];
01053   int major = lookup_dev("pcmcia");
01054   unsigned int sockets = 0;
01055   unsigned int i;
01056   vector < string > stab;
01057 
01058   if (major < 0)                                  // pcmcia support not loaded, there isn't much
01059     return false;                                 // we can do
01060 
01061   memset(fd, 0, sizeof(fd));
01062   for (i = 0; i < MAX_SOCK; i++)
01063   {
01064     fd[i] = open_dev((dev_t) ((major << 8) + i));
01065 
01066     if (fd[i] >= 0)
01067     {
01068       hwNode *parent = find_pcmciaparent(i, n);
01069       cs_status_t status;
01070       if (i >= sockets)
01071         sockets = i + 1;
01072 
01073 // check that slot is populated
01074       memset(&status, 0, sizeof(status));
01075       status.Function = 0;
01076 
01077       ioctl(fd[i], DS_GET_STATUS, &status);
01078       if (status.CardState & CS_EVENT_CARD_DETECT)
01079       {
01080         if (parent)
01081           pcmcia_ident(i, fd[i], parent);
01082         else
01083           pcmcia_ident(i, fd[i], &n);
01084       }
01085     }
01086     else
01087       break;
01088   }
01089 
01090   for (unsigned int j = 0; j < sockets; j++)
01091   {
01092     close(fd[j]);
01093   }
01094 
01095   if (loadfile(VARLIBPCMCIASTAB, stab))
01096   {
01097     string socketname = "";
01098     string carddescription = "";
01099 
01100     for (i = 0; i < stab.size(); i++)
01101     {
01102       if (stab[i][0] == 'S')
01103       {
01104         string::size_type pos = stab[i].find(':');
01105 
01106         socketname = "";
01107         carddescription = "";
01108 
01109         if (pos != string::npos)
01110         {
01111           socketname = stab[i].substr(0, pos);
01112           carddescription = stab[i].substr(pos + 1);
01113         }
01114         else
01115         {
01116           carddescription = stab[i];
01117           socketname = "";
01118         }
01119       }
01120       else
01121       {
01122         int cnt = 0;
01123         int unused = 0;
01124         int socket = -1, devmajor = 0, devminor = 0;
01125         char devclass[20], driver[20], logicalname[20];
01126 
01127         memset(devclass, 0, sizeof(devclass));
01128         memset(driver, 0, sizeof(driver));
01129         memset(logicalname, 0, sizeof(logicalname));
01130 
01131         cnt = sscanf(stab[i].c_str(),
01132           "%d %s %s %d %s %d %d",
01133           &socket, devclass, driver, &unused, logicalname,
01134           &devmajor, &devminor);
01135 
01136         if ((cnt == 7) || (cnt == 5))             // we found a correct entry
01137         {
01138           string devclassstr = string(devclass);
01139           hwNode *parent = n.findChildByHandle(pcmcia_handle(socket));
01140 
01141           if (socket >= (int) sockets)
01142             sockets = socket + 1;
01143 
01144           hwNode device = hwNode(devclass, hw::generic);
01145 
01146           if (devclassstr == "serial")
01147             device = hwNode(devclass, hw::communication);
01148           else if (devclassstr == "ide")
01149             device = hwNode(devclass, hw::storage);
01150           else if (devclassstr == "memory")
01151             device = hwNode(devclass, hw::memory);
01152           else if (devclassstr == "network")
01153             device = hwNode(devclass, hw::network);
01154 
01155           device.setLogicalName(logicalname);
01156           device.setConfig("driver", driver);
01157           device.claim();
01158 
01159           if (!parent)
01160           {
01161             parent = find_pcmciaparent(socket, n);
01162 
01163             if (parent)
01164             {
01165               hwNode *realparent = parent->getChild(0);
01166               if (!realparent)
01167               {
01168                 parent = parent->addChild(hwNode("pccard"));
01169                 parent->setHandle(pcmcia_handle(socket));
01170               }
01171               else
01172                 parent = realparent;
01173             }
01174           }
01175 
01176           if (parent)
01177           {
01178             parent->setSlot(socketname);
01179             if (parent->getDescription() == "")
01180               parent->setDescription(carddescription);
01181             parent->addChild(device);
01182           }
01183           else
01184             n.addChild(device);
01185         }
01186       }
01187     }
01188   }
01189 
01190   return true;
01191 }