From d7cd6603b45de62cd419064391d55befe495e3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 25 Oct 2005 20:43:11 +0000 Subject: [PATCH] added pcmcia headers and command line tools from pcmcia-cs-3.2.8 tested ok on Dano note that _IO* macros were redefined for the R5 target, the ones in Haiku aren't compatible with R5 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14524 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/pcmcia/bulkmem.h | 195 +++++ headers/os/drivers/pcmcia/cisreg.h | 135 +++ headers/os/drivers/pcmcia/cistpl.h | 604 +++++++++++++ headers/os/drivers/pcmcia/config.h | 9 + headers/os/drivers/pcmcia/cs.h | 441 ++++++++++ headers/os/drivers/pcmcia/cs_types.h | 70 ++ headers/os/drivers/pcmcia/driver_ops.h | 73 ++ headers/os/drivers/pcmcia/ds.h | 160 ++++ headers/os/drivers/pcmcia/ftl.h | 62 ++ headers/os/drivers/pcmcia/ss.h | 119 +++ headers/os/drivers/pcmcia/version.h | 13 + src/bin/pcmcia-cs/Jamfile | 7 + src/bin/pcmcia-cs/cardctl.8 | 97 +++ src/bin/pcmcia-cs/cardctl.c | 765 ++++++++++++++++ src/bin/pcmcia-cs/dump_cis.8 | 48 + src/bin/pcmcia-cs/dump_cis.c | 1112 ++++++++++++++++++++++++ src/bin/pcmcia-cs/dump_cisreg.c | 288 ++++++ 17 files changed, 4198 insertions(+) create mode 100644 headers/os/drivers/pcmcia/bulkmem.h create mode 100644 headers/os/drivers/pcmcia/cisreg.h create mode 100644 headers/os/drivers/pcmcia/cistpl.h create mode 100644 headers/os/drivers/pcmcia/config.h create mode 100644 headers/os/drivers/pcmcia/cs.h create mode 100644 headers/os/drivers/pcmcia/cs_types.h create mode 100644 headers/os/drivers/pcmcia/driver_ops.h create mode 100644 headers/os/drivers/pcmcia/ds.h create mode 100644 headers/os/drivers/pcmcia/ftl.h create mode 100644 headers/os/drivers/pcmcia/ss.h create mode 100644 headers/os/drivers/pcmcia/version.h create mode 100644 src/bin/pcmcia-cs/Jamfile create mode 100644 src/bin/pcmcia-cs/cardctl.8 create mode 100644 src/bin/pcmcia-cs/cardctl.c create mode 100644 src/bin/pcmcia-cs/dump_cis.8 create mode 100644 src/bin/pcmcia-cs/dump_cis.c create mode 100644 src/bin/pcmcia-cs/dump_cisreg.c diff --git a/headers/os/drivers/pcmcia/bulkmem.h b/headers/os/drivers/pcmcia/bulkmem.h new file mode 100644 index 0000000000..7748d44329 --- /dev/null +++ b/headers/os/drivers/pcmcia/bulkmem.h @@ -0,0 +1,195 @@ +/* + * Definitions for bulk memory services + * + * bulkmem.h 1.13 2001/08/24 12:16:12 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + * bulkmem.h 1.3 1995/05/27 04:49:49 + */ + +#ifndef _LINUX_BULKMEM_H +#define _LINUX_BULKMEM_H + +/* For GetFirstRegion and GetNextRegion */ +typedef struct region_info_t { + u_int Attributes; + u_int CardOffset; + u_int RegionSize; + u_int AccessSpeed; + u_int BlockSize; + u_int PartMultiple; + u_char JedecMfr, JedecInfo; + memory_handle_t next; +} region_info_t; + +#define REGION_TYPE 0x0001 +#define REGION_TYPE_CM 0x0000 +#define REGION_TYPE_AM 0x0001 +#define REGION_PREFETCH 0x0008 +#define REGION_CACHEABLE 0x0010 +#define REGION_BAR_MASK 0xe000 +#define REGION_BAR_SHIFT 13 + +/* For OpenMemory */ +typedef struct open_mem_t { + u_int Attributes; + u_int Offset; +} open_mem_t; + +/* Attributes for OpenMemory */ +#define MEMORY_TYPE 0x0001 +#define MEMORY_TYPE_CM 0x0000 +#define MEMORY_TYPE_AM 0x0001 +#define MEMORY_EXCLUSIVE 0x0002 +#define MEMORY_PREFETCH 0x0008 +#define MEMORY_CACHEABLE 0x0010 +#define MEMORY_BAR_MASK 0xe000 +#define MEMORY_BAR_SHIFT 13 + +typedef struct eraseq_entry_t { + memory_handle_t Handle; + u_char State; + u_int Size; + u_int Offset; + void *Optional; +} eraseq_entry_t; + +typedef struct eraseq_hdr_t { + int QueueEntryCnt; + eraseq_entry_t *QueueEntryArray; +} eraseq_hdr_t; + +#define ERASE_QUEUED 0x00 +#define ERASE_IN_PROGRESS(n) (((n) > 0) && ((n) < 0x80)) +#define ERASE_IDLE 0xff +#define ERASE_PASSED 0xe0 +#define ERASE_FAILED 0xe1 + +#define ERASE_MISSING 0x80 +#define ERASE_MEDIA_WRPROT 0x84 +#define ERASE_NOT_ERASABLE 0x85 +#define ERASE_BAD_OFFSET 0xc1 +#define ERASE_BAD_TECH 0xc2 +#define ERASE_BAD_SOCKET 0xc3 +#define ERASE_BAD_VCC 0xc4 +#define ERASE_BAD_VPP 0xc5 +#define ERASE_BAD_SIZE 0xc6 + +/* For CopyMemory */ +typedef struct copy_op_t { + u_int Attributes; + u_int SourceOffset; + u_int DestOffset; + u_int Count; +} copy_op_t; + +/* For ReadMemory and WriteMemory */ +typedef struct mem_op_t { + u_int Attributes; + u_int Offset; + u_int Count; +} mem_op_t; + +#define MEM_OP_BUFFER 0x01 +#define MEM_OP_BUFFER_USER 0x00 +#define MEM_OP_BUFFER_KERNEL 0x01 +#define MEM_OP_DISABLE_ERASE 0x02 +#define MEM_OP_VERIFY 0x04 + +/* For RegisterMTD */ +typedef struct mtd_reg_t { + u_int Attributes; + u_int Offset; + u_long MediaID; +} mtd_reg_t; + +/* + * Definitions for MTD requests + */ + +typedef struct mtd_request_t { + u_int SrcCardOffset; + u_int DestCardOffset; + u_int TransferLength; + u_int Function; + u_long MediaID; + u_int Status; + u_int Timeout; +} mtd_request_t; + +/* Fields in MTD Function */ +#define MTD_REQ_ACTION 0x003 +#define MTD_REQ_ERASE 0x000 +#define MTD_REQ_READ 0x001 +#define MTD_REQ_WRITE 0x002 +#define MTD_REQ_COPY 0x003 +#define MTD_REQ_NOERASE 0x004 +#define MTD_REQ_VERIFY 0x008 +#define MTD_REQ_READY 0x010 +#define MTD_REQ_TIMEOUT 0x020 +#define MTD_REQ_LAST 0x040 +#define MTD_REQ_FIRST 0x080 +#define MTD_REQ_KERNEL 0x100 + +/* Status codes */ +#define MTD_WAITREQ 0x00 +#define MTD_WAITTIMER 0x01 +#define MTD_WAITRDY 0x02 +#define MTD_WAITPOWER 0x03 + +/* + * Definitions for MTD helper functions + */ + +/* For MTDModifyWindow */ +typedef struct mtd_mod_win_t { + u_int Attributes; + u_int AccessSpeed; + u_int CardOffset; +} mtd_mod_win_t; + +/* For MTDSetVpp */ +typedef struct mtd_vpp_req_t { + u_char Vpp1, Vpp2; +} mtd_vpp_req_t; + +/* For MTDRDYMask */ +typedef struct mtd_rdy_req_t { + u_int Mask; +} mtd_rdy_req_t; + +enum mtd_helper { + MTDRequestWindow, MTDModifyWindow, MTDReleaseWindow, + MTDSetVpp, MTDRDYMask +}; + +#ifdef IN_CARD_SERVICES +extern int MTDHelperEntry(int func, void *a1, void *a2); +#else +extern int MTDHelperEntry(int func, ...); +#endif + +#endif /* _LINUX_BULKMEM_H */ diff --git a/headers/os/drivers/pcmcia/cisreg.h b/headers/os/drivers/pcmcia/cisreg.h new file mode 100644 index 0000000000..cb9fe39219 --- /dev/null +++ b/headers/os/drivers/pcmcia/cisreg.h @@ -0,0 +1,135 @@ +/* + * cisreg.h 1.18 2001/08/24 12:16:12 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef _LINUX_CISREG_H +#define _LINUX_CISREG_H + +/* + * Offsets from ConfigBase for CIS registers + */ +#define CISREG_COR 0x00 +#define CISREG_CCSR 0x02 +#define CISREG_PRR 0x04 +#define CISREG_SCR 0x06 +#define CISREG_ESR 0x08 +#define CISREG_IOBASE_0 0x0a +#define CISREG_IOBASE_1 0x0c +#define CISREG_IOBASE_2 0x0e +#define CISREG_IOBASE_3 0x10 +#define CISREG_IOSIZE 0x12 + +/* + * Configuration Option Register + */ +#define COR_CONFIG_MASK 0x3f +#define COR_MFC_CONFIG_MASK 0x38 +#define COR_FUNC_ENA 0x01 +#define COR_ADDR_DECODE 0x02 +#define COR_IREQ_ENA 0x04 +#define COR_LEVEL_REQ 0x40 +#define COR_SOFT_RESET 0x80 + +/* + * Card Configuration and Status Register + */ +#define CCSR_INTR_ACK 0x01 +#define CCSR_INTR_PENDING 0x02 +#define CCSR_POWER_DOWN 0x04 +#define CCSR_AUDIO_ENA 0x08 +#define CCSR_IOIS8 0x20 +#define CCSR_SIGCHG_ENA 0x40 +#define CCSR_CHANGED 0x80 + +/* + * Pin Replacement Register + */ +#define PRR_WP_STATUS 0x01 +#define PRR_READY_STATUS 0x02 +#define PRR_BVD2_STATUS 0x04 +#define PRR_BVD1_STATUS 0x08 +#define PRR_WP_EVENT 0x10 +#define PRR_READY_EVENT 0x20 +#define PRR_BVD2_EVENT 0x40 +#define PRR_BVD1_EVENT 0x80 + +/* + * Socket and Copy Register + */ +#define SCR_SOCKET_NUM 0x0f +#define SCR_COPY_NUM 0x70 + +/* + * Extended Status Register + */ +#define ESR_REQ_ATTN_ENA 0x01 +#define ESR_REQ_ATTN 0x10 + +/* + * CardBus Function Status Registers + */ +#define CBFN_EVENT 0x00 +#define CBFN_MASK 0x04 +#define CBFN_STATE 0x08 +#define CBFN_FORCE 0x0c + +/* + * These apply to all the CardBus function registers + */ +#define CBFN_WP 0x0001 +#define CBFN_READY 0x0002 +#define CBFN_BVD2 0x0004 +#define CBFN_BVD1 0x0008 +#define CBFN_GWAKE 0x0010 +#define CBFN_INTR 0x8000 + +/* + * Extra bits in the Function Event Mask Register + */ +#define FEMR_BAM_ENA 0x0020 +#define FEMR_PWM_ENA 0x0040 +#define FEMR_WKUP_MASK 0x4000 + +/* + * Indirect Addressing Registers for Zoomed Video: these are addresses + * in common memory space + */ +#define CISREG_ICTRL0 0x02 /* control registers */ +#define CISREG_ICTRL1 0x03 +#define CISREG_IADDR0 0x04 /* address registers */ +#define CISREG_IADDR1 0x05 +#define CISREG_IADDR2 0x06 +#define CISREG_IADDR3 0x07 +#define CISREG_IDATA0 0x08 /* data registers */ +#define CISREG_IDATA1 0x09 + +#define ICTRL0_COMMON 0x01 +#define ICTRL0_AUTOINC 0x02 +#define ICTRL0_BYTEGRAN 0x04 + +#endif /* _LINUX_CISREG_H */ diff --git a/headers/os/drivers/pcmcia/cistpl.h b/headers/os/drivers/pcmcia/cistpl.h new file mode 100644 index 0000000000..1d4cac20e3 --- /dev/null +++ b/headers/os/drivers/pcmcia/cistpl.h @@ -0,0 +1,604 @@ +/* + * cistpl.h 1.35 2001/08/24 12:16:12 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef _LINUX_CISTPL_H +#define _LINUX_CISTPL_H + +#define CISTPL_NULL 0x00 +#define CISTPL_DEVICE 0x01 +#define CISTPL_LONGLINK_CB 0x02 +#define CISTPL_INDIRECT 0x03 +#define CISTPL_CONFIG_CB 0x04 +#define CISTPL_CFTABLE_ENTRY_CB 0x05 +#define CISTPL_LONGLINK_MFC 0x06 +#define CISTPL_BAR 0x07 +#define CISTPL_PWR_MGMNT 0x08 +#define CISTPL_EXTDEVICE 0x09 +#define CISTPL_CHECKSUM 0x10 +#define CISTPL_LONGLINK_A 0x11 +#define CISTPL_LONGLINK_C 0x12 +#define CISTPL_LINKTARGET 0x13 +#define CISTPL_NO_LINK 0x14 +#define CISTPL_VERS_1 0x15 +#define CISTPL_ALTSTR 0x16 +#define CISTPL_DEVICE_A 0x17 +#define CISTPL_JEDEC_C 0x18 +#define CISTPL_JEDEC_A 0x19 +#define CISTPL_CONFIG 0x1a +#define CISTPL_CFTABLE_ENTRY 0x1b +#define CISTPL_DEVICE_OC 0x1c +#define CISTPL_DEVICE_OA 0x1d +#define CISTPL_DEVICE_GEO 0x1e +#define CISTPL_DEVICE_GEO_A 0x1f +#define CISTPL_MANFID 0x20 +#define CISTPL_FUNCID 0x21 +#define CISTPL_FUNCE 0x22 +#define CISTPL_SWIL 0x23 +#define CISTPL_END 0xff +/* Layer 2 tuples */ +#define CISTPL_VERS_2 0x40 +#define CISTPL_FORMAT 0x41 +#define CISTPL_GEOMETRY 0x42 +#define CISTPL_BYTEORDER 0x43 +#define CISTPL_DATE 0x44 +#define CISTPL_BATTERY 0x45 +#define CISTPL_FORMAT_A 0x47 +/* Layer 3 tuples */ +#define CISTPL_ORG 0x46 +#define CISTPL_SPCL 0x90 + +typedef struct cistpl_longlink_t { + u_int addr; +} cistpl_longlink_t; + +typedef struct cistpl_checksum_t { + u_short addr; + u_short len; + u_char sum; +} cistpl_checksum_t; + +#define CISTPL_MAX_FUNCTIONS 8 +#define CISTPL_MFC_ATTR 0x00 +#define CISTPL_MFC_COMMON 0x01 + +typedef struct cistpl_longlink_mfc_t { + u_char nfn; + struct { + u_char space; + u_int addr; + } fn[CISTPL_MAX_FUNCTIONS]; +} cistpl_longlink_mfc_t; + +#define CISTPL_MAX_ALTSTR_STRINGS 4 + +typedef struct cistpl_altstr_t { + u_char ns; + u_char ofs[CISTPL_MAX_ALTSTR_STRINGS]; + char str[254]; +} cistpl_altstr_t; + +#define CISTPL_DTYPE_NULL 0x00 +#define CISTPL_DTYPE_ROM 0x01 +#define CISTPL_DTYPE_OTPROM 0x02 +#define CISTPL_DTYPE_EPROM 0x03 +#define CISTPL_DTYPE_EEPROM 0x04 +#define CISTPL_DTYPE_FLASH 0x05 +#define CISTPL_DTYPE_SRAM 0x06 +#define CISTPL_DTYPE_DRAM 0x07 +#define CISTPL_DTYPE_FUNCSPEC 0x0d +#define CISTPL_DTYPE_EXTEND 0x0e + +#define CISTPL_MAX_DEVICES 4 + +typedef struct cistpl_device_t { + u_char ndev; + struct { + u_char type; + u_char wp; + u_int speed; + u_int size; + } dev[CISTPL_MAX_DEVICES]; +} cistpl_device_t; + +#define CISTPL_DEVICE_MWAIT 0x01 +#define CISTPL_DEVICE_3VCC 0x02 + +typedef struct cistpl_device_o_t { + u_char flags; + cistpl_device_t device; +} cistpl_device_o_t; + +#define CISTPL_VERS_1_MAX_PROD_STRINGS 4 + +typedef struct cistpl_vers_1_t { + u_char major; + u_char minor; + u_char ns; + u_char ofs[CISTPL_VERS_1_MAX_PROD_STRINGS]; + char str[254]; +} cistpl_vers_1_t; + +typedef struct cistpl_jedec_t { + u_char nid; + struct { + u_char mfr; + u_char info; + } id[CISTPL_MAX_DEVICES]; +} cistpl_jedec_t; + +typedef struct cistpl_manfid_t { + u_short manf; + u_short card; +} cistpl_manfid_t; + +#define CISTPL_FUNCID_MULTI 0x00 +#define CISTPL_FUNCID_MEMORY 0x01 +#define CISTPL_FUNCID_SERIAL 0x02 +#define CISTPL_FUNCID_PARALLEL 0x03 +#define CISTPL_FUNCID_FIXED 0x04 +#define CISTPL_FUNCID_VIDEO 0x05 +#define CISTPL_FUNCID_NETWORK 0x06 +#define CISTPL_FUNCID_AIMS 0x07 +#define CISTPL_FUNCID_SCSI 0x08 + +#define CISTPL_SYSINIT_POST 0x01 +#define CISTPL_SYSINIT_ROM 0x02 + +typedef struct cistpl_funcid_t { + u_char func; + u_char sysinit; +} cistpl_funcid_t; + +typedef struct cistpl_funce_t { + u_char type; + u_char data[0]; +} cistpl_funce_t; + +/*====================================================================== + + Modem Function Extension Tuples + +======================================================================*/ + +#define CISTPL_FUNCE_SERIAL_IF 0x00 +#define CISTPL_FUNCE_SERIAL_CAP 0x01 +#define CISTPL_FUNCE_SERIAL_SERV_DATA 0x02 +#define CISTPL_FUNCE_SERIAL_SERV_FAX 0x03 +#define CISTPL_FUNCE_SERIAL_SERV_VOICE 0x04 +#define CISTPL_FUNCE_SERIAL_CAP_DATA 0x05 +#define CISTPL_FUNCE_SERIAL_CAP_FAX 0x06 +#define CISTPL_FUNCE_SERIAL_CAP_VOICE 0x07 +#define CISTPL_FUNCE_SERIAL_IF_DATA 0x08 +#define CISTPL_FUNCE_SERIAL_IF_FAX 0x09 +#define CISTPL_FUNCE_SERIAL_IF_VOICE 0x0a + +/* UART identification */ +#define CISTPL_SERIAL_UART_8250 0x00 +#define CISTPL_SERIAL_UART_16450 0x01 +#define CISTPL_SERIAL_UART_16550 0x02 +#define CISTPL_SERIAL_UART_8251 0x03 +#define CISTPL_SERIAL_UART_8530 0x04 +#define CISTPL_SERIAL_UART_85230 0x05 + +/* UART capabilities */ +#define CISTPL_SERIAL_UART_SPACE 0x01 +#define CISTPL_SERIAL_UART_MARK 0x02 +#define CISTPL_SERIAL_UART_ODD 0x04 +#define CISTPL_SERIAL_UART_EVEN 0x08 +#define CISTPL_SERIAL_UART_5BIT 0x01 +#define CISTPL_SERIAL_UART_6BIT 0x02 +#define CISTPL_SERIAL_UART_7BIT 0x04 +#define CISTPL_SERIAL_UART_8BIT 0x08 +#define CISTPL_SERIAL_UART_1STOP 0x10 +#define CISTPL_SERIAL_UART_MSTOP 0x20 +#define CISTPL_SERIAL_UART_2STOP 0x40 + +typedef struct cistpl_serial_t { + u_char uart_type; + u_char uart_cap_0; + u_char uart_cap_1; +} cistpl_serial_t; + +typedef struct cistpl_modem_cap_t { + u_char flow; + u_char cmd_buf; + u_char rcv_buf_0, rcv_buf_1, rcv_buf_2; + u_char xmit_buf_0, xmit_buf_1, xmit_buf_2; +} cistpl_modem_cap_t; + +#define CISTPL_SERIAL_MOD_103 0x01 +#define CISTPL_SERIAL_MOD_V21 0x02 +#define CISTPL_SERIAL_MOD_V23 0x04 +#define CISTPL_SERIAL_MOD_V22 0x08 +#define CISTPL_SERIAL_MOD_212A 0x10 +#define CISTPL_SERIAL_MOD_V22BIS 0x20 +#define CISTPL_SERIAL_MOD_V26 0x40 +#define CISTPL_SERIAL_MOD_V26BIS 0x80 +#define CISTPL_SERIAL_MOD_V27BIS 0x01 +#define CISTPL_SERIAL_MOD_V29 0x02 +#define CISTPL_SERIAL_MOD_V32 0x04 +#define CISTPL_SERIAL_MOD_V32BIS 0x08 +#define CISTPL_SERIAL_MOD_V34 0x10 + +#define CISTPL_SERIAL_ERR_MNP2_4 0x01 +#define CISTPL_SERIAL_ERR_V42_LAPM 0x02 + +#define CISTPL_SERIAL_CMPR_V42BIS 0x01 +#define CISTPL_SERIAL_CMPR_MNP5 0x02 + +#define CISTPL_SERIAL_CMD_AT1 0x01 +#define CISTPL_SERIAL_CMD_AT2 0x02 +#define CISTPL_SERIAL_CMD_AT3 0x04 +#define CISTPL_SERIAL_CMD_MNP_AT 0x08 +#define CISTPL_SERIAL_CMD_V25BIS 0x10 +#define CISTPL_SERIAL_CMD_V25A 0x20 +#define CISTPL_SERIAL_CMD_DMCL 0x40 + +typedef struct cistpl_data_serv_t { + u_char max_data_0; + u_char max_data_1; + u_char modulation_0; + u_char modulation_1; + u_char error_control; + u_char compression; + u_char cmd_protocol; + u_char escape; + u_char encrypt; + u_char misc_features; + u_char ccitt_code[0]; +} cistpl_data_serv_t; + +typedef struct cistpl_fax_serv_t { + u_char max_data_0; + u_char max_data_1; + u_char modulation; + u_char encrypt; + u_char features_0; + u_char features_1; + u_char ccitt_code[0]; +} cistpl_fax_serv_t; + +typedef struct cistpl_voice_serv_t { + u_char max_data_0; + u_char max_data_1; +} cistpl_voice_serv_t; + +/*====================================================================== + + LAN Function Extension Tuples + +======================================================================*/ + +#define CISTPL_FUNCE_LAN_TECH 0x01 +#define CISTPL_FUNCE_LAN_SPEED 0x02 +#define CISTPL_FUNCE_LAN_MEDIA 0x03 +#define CISTPL_FUNCE_LAN_NODE_ID 0x04 +#define CISTPL_FUNCE_LAN_CONNECTOR 0x05 + +/* LAN technologies */ +#define CISTPL_LAN_TECH_ARCNET 0x01 +#define CISTPL_LAN_TECH_ETHERNET 0x02 +#define CISTPL_LAN_TECH_TOKENRING 0x03 +#define CISTPL_LAN_TECH_LOCALTALK 0x04 +#define CISTPL_LAN_TECH_FDDI 0x05 +#define CISTPL_LAN_TECH_ATM 0x06 +#define CISTPL_LAN_TECH_WIRELESS 0x07 + +typedef struct cistpl_lan_tech_t { + u_char tech; +} cistpl_lan_tech_t; + +typedef struct cistpl_lan_speed_t { + u_int speed; +} cistpl_lan_speed_t; + +/* LAN media definitions */ +#define CISTPL_LAN_MEDIA_UTP 0x01 +#define CISTPL_LAN_MEDIA_STP 0x02 +#define CISTPL_LAN_MEDIA_THIN_COAX 0x03 +#define CISTPL_LAN_MEDIA_THICK_COAX 0x04 +#define CISTPL_LAN_MEDIA_FIBER 0x05 +#define CISTPL_LAN_MEDIA_900MHZ 0x06 +#define CISTPL_LAN_MEDIA_2GHZ 0x07 +#define CISTPL_LAN_MEDIA_5GHZ 0x08 +#define CISTPL_LAN_MEDIA_DIFF_IR 0x09 +#define CISTPL_LAN_MEDIA_PTP_IR 0x0a + +typedef struct cistpl_lan_media_t { + u_char media; +} cistpl_lan_media_t; + +typedef struct cistpl_lan_node_id_t { + u_char nb; + u_char id[16]; +} cistpl_lan_node_id_t; + +typedef struct cistpl_lan_connector_t { + u_char code; +} cistpl_lan_connector_t; + +/*====================================================================== + + IDE Function Extension Tuples + +======================================================================*/ + +#define CISTPL_IDE_INTERFACE 0x01 + +typedef struct cistpl_ide_interface_t { + u_char interface; +} cistpl_ide_interface_t; + +/* First feature byte */ +#define CISTPL_IDE_SILICON 0x04 +#define CISTPL_IDE_UNIQUE 0x08 +#define CISTPL_IDE_DUAL 0x10 + +/* Second feature byte */ +#define CISTPL_IDE_HAS_SLEEP 0x01 +#define CISTPL_IDE_HAS_STANDBY 0x02 +#define CISTPL_IDE_HAS_IDLE 0x04 +#define CISTPL_IDE_LOW_POWER 0x08 +#define CISTPL_IDE_REG_INHIBIT 0x10 +#define CISTPL_IDE_HAS_INDEX 0x20 +#define CISTPL_IDE_IOIS16 0x40 + +typedef struct cistpl_ide_feature_t { + u_char feature1; + u_char feature2; +} cistpl_ide_feature_t; + +#define CISTPL_FUNCE_IDE_IFACE 0x01 +#define CISTPL_FUNCE_IDE_MASTER 0x02 +#define CISTPL_FUNCE_IDE_SLAVE 0x03 + +/*====================================================================== + + Configuration Table Entries + +======================================================================*/ + +#define CISTPL_BAR_SPACE 0x07 +#define CISTPL_BAR_SPACE_IO 0x10 +#define CISTPL_BAR_PREFETCH 0x20 +#define CISTPL_BAR_CACHEABLE 0x40 +#define CISTPL_BAR_1MEG_MAP 0x80 + +typedef struct cistpl_bar_t { + u_char attr; + u_int size; +} cistpl_bar_t; + +typedef struct cistpl_config_t { + u_char last_idx; + u_int base; + u_int rmask[4]; + u_char subtuples; +} cistpl_config_t; + +/* These are bits in the 'present' field, and indices in 'param' */ +#define CISTPL_POWER_VNOM 0 +#define CISTPL_POWER_VMIN 1 +#define CISTPL_POWER_VMAX 2 +#define CISTPL_POWER_ISTATIC 3 +#define CISTPL_POWER_IAVG 4 +#define CISTPL_POWER_IPEAK 5 +#define CISTPL_POWER_IDOWN 6 + +#define CISTPL_POWER_HIGHZ_OK 0x01 +#define CISTPL_POWER_HIGHZ_REQ 0x02 + +typedef struct cistpl_power_t { + u_char present; + u_char flags; + u_int param[7]; +} cistpl_power_t; + +typedef struct cistpl_timing_t { + u_int wait, waitscale; + u_int ready, rdyscale; + u_int reserved, rsvscale; +} cistpl_timing_t; + +#define CISTPL_IO_LINES_MASK 0x1f +#define CISTPL_IO_8BIT 0x20 +#define CISTPL_IO_16BIT 0x40 +#define CISTPL_IO_RANGE 0x80 + +#define CISTPL_IO_MAX_WIN 16 + +typedef struct cistpl_io_t { + u_char flags; + u_char nwin; + struct { + u_int base; + u_int len; + } win[CISTPL_IO_MAX_WIN]; +} cistpl_io_t; + +typedef struct cistpl_irq_t { + u_int IRQInfo1; + u_int IRQInfo2; +} cistpl_irq_t; + +#define CISTPL_MEM_MAX_WIN 8 + +typedef struct cistpl_mem_t { + u_char flags; + u_char nwin; + struct { + u_int len; + u_int card_addr; + u_int host_addr; + } win[CISTPL_MEM_MAX_WIN]; +} cistpl_mem_t; + +#define CISTPL_CFTABLE_DEFAULT 0x0001 +#define CISTPL_CFTABLE_BVDS 0x0002 +#define CISTPL_CFTABLE_WP 0x0004 +#define CISTPL_CFTABLE_RDYBSY 0x0008 +#define CISTPL_CFTABLE_MWAIT 0x0010 +#define CISTPL_CFTABLE_AUDIO 0x0800 +#define CISTPL_CFTABLE_READONLY 0x1000 +#define CISTPL_CFTABLE_PWRDOWN 0x2000 + +typedef struct cistpl_cftable_entry_t { + u_char index; + u_short flags; + u_char interface; + cistpl_power_t vcc, vpp1, vpp2; + cistpl_timing_t timing; + cistpl_io_t io; + cistpl_irq_t irq; + cistpl_mem_t mem; + u_char subtuples; +} cistpl_cftable_entry_t; + +#define CISTPL_CFTABLE_MASTER 0x000100 +#define CISTPL_CFTABLE_INVALIDATE 0x000200 +#define CISTPL_CFTABLE_VGA_PALETTE 0x000400 +#define CISTPL_CFTABLE_PARITY 0x000800 +#define CISTPL_CFTABLE_WAIT 0x001000 +#define CISTPL_CFTABLE_SERR 0x002000 +#define CISTPL_CFTABLE_FAST_BACK 0x004000 +#define CISTPL_CFTABLE_BINARY_AUDIO 0x010000 +#define CISTPL_CFTABLE_PWM_AUDIO 0x020000 + +typedef struct cistpl_cftable_entry_cb_t { + u_char index; + u_int flags; + cistpl_power_t vcc, vpp1, vpp2; + u_char io; + cistpl_irq_t irq; + u_char mem; + u_char subtuples; +} cistpl_cftable_entry_cb_t; + +typedef struct cistpl_device_geo_t { + u_char ngeo; + struct { + u_char buswidth; + u_int erase_block; + u_int read_block; + u_int write_block; + u_int partition; + u_int interleave; + } geo[CISTPL_MAX_DEVICES]; +} cistpl_device_geo_t; + +typedef struct cistpl_vers_2_t { + u_char vers; + u_char comply; + u_short dindex; + u_char vspec8, vspec9; + u_char nhdr; + u_char vendor, info; + char str[244]; +} cistpl_vers_2_t; + +typedef struct cistpl_org_t { + u_char data_org; + char desc[30]; +} cistpl_org_t; + +#define CISTPL_ORG_FS 0x00 +#define CISTPL_ORG_APPSPEC 0x01 +#define CISTPL_ORG_XIP 0x02 + +typedef struct cistpl_format_t { + u_char type; + u_char edc; + u_int offset; + u_int length; +} cistpl_format_t; + +#define CISTPL_FORMAT_DISK 0x00 +#define CISTPL_FORMAT_MEM 0x01 + +#define CISTPL_EDC_NONE 0x00 +#define CISTPL_EDC_CKSUM 0x01 +#define CISTPL_EDC_CRC 0x02 +#define CISTPL_EDC_PCC 0x03 + +typedef union cisparse_t { + cistpl_device_t device; + cistpl_checksum_t checksum; + cistpl_longlink_t longlink; + cistpl_longlink_mfc_t longlink_mfc; + cistpl_vers_1_t version_1; + cistpl_altstr_t altstr; + cistpl_jedec_t jedec; + cistpl_manfid_t manfid; + cistpl_funcid_t funcid; + cistpl_funce_t funce; + cistpl_bar_t bar; + cistpl_config_t config; + cistpl_cftable_entry_t cftable_entry; + cistpl_cftable_entry_cb_t cftable_entry_cb; + cistpl_device_geo_t device_geo; + cistpl_vers_2_t vers_2; + cistpl_org_t org; + cistpl_format_t format; +} cisparse_t; + +typedef struct tuple_t { + u_int Attributes; + cisdata_t DesiredTuple; + u_int Flags; /* internal use */ + u_int LinkOffset; /* internal use */ + u_int CISOffset; /* internal use */ + cisdata_t TupleCode; + cisdata_t TupleLink; + cisdata_t TupleOffset; + cisdata_t TupleDataMax; + cisdata_t TupleDataLen; + cisdata_t *TupleData; +} tuple_t; + +/* Special cisdata_t value */ +#define RETURN_FIRST_TUPLE 0xff + +/* Attributes for tuple calls */ +#define TUPLE_RETURN_LINK 0x01 +#define TUPLE_RETURN_COMMON 0x02 + +/* For ValidateCIS */ +typedef struct cisinfo_t { + u_int Chains; +} cisinfo_t; + +#define CISTPL_MAX_CIS_SIZE 0x200 + +/* For ReplaceCIS */ +typedef struct cisdump_t { + u_int Length; + cisdata_t Data[CISTPL_MAX_CIS_SIZE]; +} cisdump_t; + +#endif /* LINUX_CISTPL_H */ diff --git a/headers/os/drivers/pcmcia/config.h b/headers/os/drivers/pcmcia/config.h new file mode 100644 index 0000000000..f2ba3e412c --- /dev/null +++ b/headers/os/drivers/pcmcia/config.h @@ -0,0 +1,9 @@ +#ifndef _PCMCIA_CONFIG_H +#define _PCMCIA_CONFIG_H + +#define AUTOCONF_INCLUDED +#define __IN_PCMCIA_PACKAGE__ + +//#include + +#endif /* _PCMCIA_CONFIG_H */ diff --git a/headers/os/drivers/pcmcia/cs.h b/headers/os/drivers/pcmcia/cs.h new file mode 100644 index 0000000000..8e202c6788 --- /dev/null +++ b/headers/os/drivers/pcmcia/cs.h @@ -0,0 +1,441 @@ +/* + * cs.h 1.74 2001/10/04 03:15:22 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef _LINUX_CS_H +#define _LINUX_CS_H + +/* For AccessConfigurationRegister */ +typedef struct conf_reg_t { + u_char Function; + u_int Action; + off_t Offset; + u_int Value; +} conf_reg_t; + +/* Actions */ +#define CS_READ 1 +#define CS_WRITE 2 + +/* for AdjustResourceInfo */ +typedef struct adjust_t { + u_int Action; + u_int Resource; + u_int Attributes; + union { + struct memory { + u_long Base; + u_long Size; + } memory; + struct io { + ioaddr_t BasePort; + ioaddr_t NumPorts; + u_int IOAddrLines; + } io; + struct irq { + u_int IRQ; + } irq; + } resource; +} adjust_t; + +/* Action field */ +#define REMOVE_MANAGED_RESOURCE 1 +#define ADD_MANAGED_RESOURCE 2 +#define GET_FIRST_MANAGED_RESOURCE 3 +#define GET_NEXT_MANAGED_RESOURCE 4 +/* Resource field */ +#define RES_MEMORY_RANGE 1 +#define RES_IO_RANGE 2 +#define RES_IRQ 3 +/* Attribute field */ +#define RES_IRQ_TYPE 0x03 +#define RES_IRQ_TYPE_EXCLUSIVE 0 +#define RES_IRQ_TYPE_TIME 1 +#define RES_IRQ_TYPE_DYNAMIC 2 +#define RES_IRQ_CSC 0x04 +#define RES_SHARED 0x08 +#define RES_RESERVED 0x10 +#define RES_ALLOCATED 0x20 +#define RES_REMOVED 0x40 + +typedef struct servinfo_t { + char Signature[2]; + u_int Count; + u_int Revision; + u_int CSLevel; + char *VendorString; +} servinfo_t; + +typedef struct event_callback_args_t { + client_handle_t client_handle; + void *info; + void *mtdrequest; + void *buffer; + void *misc; + void *client_data; + struct bus_operations *bus; +} event_callback_args_t; + +/* for GetConfigurationInfo */ +typedef struct config_info_t { + u_char Function; + u_int Attributes; + u_int Vcc, Vpp1, Vpp2; + u_int IntType; + u_int ConfigBase; + u_char Status, Pin, Copy, Option, ExtStatus; + u_int Present; + u_int CardValues; + u_int AssignedIRQ; + u_int IRQAttributes; + ioaddr_t BasePort1; + ioaddr_t NumPorts1; + u_int Attributes1; + ioaddr_t BasePort2; + ioaddr_t NumPorts2; + u_int Attributes2; + u_int IOAddrLines; +} config_info_t; + +/* For CardValues field */ +#define CV_OPTION_VALUE 0x01 +#define CV_STATUS_VALUE 0x02 +#define CV_PIN_REPLACEMENT 0x04 +#define CV_COPY_VALUE 0x08 +#define CV_EXT_STATUS 0x10 + +/* For GetFirst/NextClient */ +typedef struct client_req_t { + socket_t Socket; + u_int Attributes; +} client_req_t; + +#define CLIENT_THIS_SOCKET 0x01 + +/* For RegisterClient */ +typedef struct client_reg_t { + dev_info_t *dev_info; + u_int Attributes; + u_int EventMask; + int (*event_handler)(event_t event, int priority, + event_callback_args_t *); + event_callback_args_t event_callback_args; + u_int Version; +} client_reg_t; + +/* ModifyConfiguration */ +typedef struct modconf_t { + u_int Attributes; + u_int Vcc, Vpp1, Vpp2; +} modconf_t; + +/* Attributes for ModifyConfiguration */ +#define CONF_IRQ_CHANGE_VALID 0x100 +#define CONF_VCC_CHANGE_VALID 0x200 +#define CONF_VPP1_CHANGE_VALID 0x400 +#define CONF_VPP2_CHANGE_VALID 0x800 + +/* For RequestConfiguration */ +typedef struct config_req_t { + u_int Attributes; + u_int Vcc, Vpp1, Vpp2; + u_int IntType; + u_int ConfigBase; + u_char Status, Pin, Copy, ExtStatus; + u_char ConfigIndex; + u_int Present; +} config_req_t; + +/* Attributes for RequestConfiguration */ +#define CONF_ENABLE_IRQ 0x01 +#define CONF_ENABLE_DMA 0x02 +#define CONF_ENABLE_SPKR 0x04 +#define CONF_VALID_CLIENT 0x100 + +/* IntType field */ +#define INT_MEMORY 0x01 +#define INT_MEMORY_AND_IO 0x02 +#define INT_CARDBUS 0x04 +#define INT_ZOOMED_VIDEO 0x08 + +/* For RequestIO and ReleaseIO */ +typedef struct io_req_t { + ioaddr_t BasePort1; + ioaddr_t NumPorts1; + u_int Attributes1; + ioaddr_t BasePort2; + ioaddr_t NumPorts2; + u_int Attributes2; + u_int IOAddrLines; +} io_req_t; + +/* Attributes for RequestIO and ReleaseIO */ +#define IO_SHARED 0x01 +#define IO_FIRST_SHARED 0x02 +#define IO_FORCE_ALIAS_ACCESS 0x04 +#define IO_DATA_PATH_WIDTH 0x18 +#define IO_DATA_PATH_WIDTH_8 0x00 +#define IO_DATA_PATH_WIDTH_16 0x08 +#define IO_DATA_PATH_WIDTH_AUTO 0x10 + +/* For RequestIRQ and ReleaseIRQ */ +typedef struct irq_req_t { + u_int Attributes; + u_int AssignedIRQ; + u_int IRQInfo1, IRQInfo2; + void *Handler; + void *Instance; +} irq_req_t; + +/* Attributes for RequestIRQ and ReleaseIRQ */ +#define IRQ_TYPE 0x03 +#define IRQ_TYPE_EXCLUSIVE 0x00 +#define IRQ_TYPE_TIME 0x01 +#define IRQ_TYPE_DYNAMIC_SHARING 0x02 +#define IRQ_FORCED_PULSE 0x04 +#define IRQ_FIRST_SHARED 0x08 +#define IRQ_HANDLE_PRESENT 0x10 +#define IRQ_PULSE_ALLOCATED 0x100 + +/* Bits in IRQInfo1 field */ +#define IRQ_MASK 0x0f +#define IRQ_NMI_ID 0x01 +#define IRQ_IOCK_ID 0x02 +#define IRQ_BERR_ID 0x04 +#define IRQ_VEND_ID 0x08 +#define IRQ_INFO2_VALID 0x10 +#define IRQ_LEVEL_ID 0x20 +#define IRQ_PULSE_ID 0x40 +#define IRQ_SHARE_ID 0x80 + +typedef struct eventmask_t { + u_int Attributes; + u_int EventMask; +} eventmask_t; + +#define CONF_EVENT_MASK_VALID 0x01 + +/* Configuration registers present */ +#define PRESENT_OPTION 0x001 +#define PRESENT_STATUS 0x002 +#define PRESENT_PIN_REPLACE 0x004 +#define PRESENT_COPY 0x008 +#define PRESENT_EXT_STATUS 0x010 +#define PRESENT_IOBASE_0 0x020 +#define PRESENT_IOBASE_1 0x040 +#define PRESENT_IOBASE_2 0x080 +#define PRESENT_IOBASE_3 0x100 +#define PRESENT_IOSIZE 0x200 + +/* For GetMemPage, MapMemPage */ +typedef struct memreq_t { + u_int CardOffset; + page_t Page; +} memreq_t; + +/* For ModifyWindow */ +typedef struct modwin_t { + u_int Attributes; + u_int AccessSpeed; +} modwin_t; + +/* For RequestWindow */ +typedef struct win_req_t { + u_int Attributes; + u_long Base; + u_int Size; + u_int AccessSpeed; +} win_req_t; + +/* Attributes for RequestWindow */ +#define WIN_ADDR_SPACE 0x0001 +#define WIN_ADDR_SPACE_MEM 0x0000 +#define WIN_ADDR_SPACE_IO 0x0001 +#define WIN_MEMORY_TYPE 0x0002 +#define WIN_MEMORY_TYPE_CM 0x0000 +#define WIN_MEMORY_TYPE_AM 0x0002 +#define WIN_ENABLE 0x0004 +#define WIN_DATA_WIDTH 0x0018 +#define WIN_DATA_WIDTH_8 0x0000 +#define WIN_DATA_WIDTH_16 0x0008 +#define WIN_DATA_WIDTH_32 0x0010 +#define WIN_PAGED 0x0020 +#define WIN_SHARED 0x0040 +#define WIN_FIRST_SHARED 0x0080 +#define WIN_USE_WAIT 0x0100 +#define WIN_STRICT_ALIGN 0x0200 +#define WIN_MAP_BELOW_1MB 0x0400 +#define WIN_PREFETCH 0x0800 +#define WIN_CACHEABLE 0x1000 +#define WIN_BAR_MASK 0xe000 +#define WIN_BAR_SHIFT 13 + +/* Attributes for RegisterClient */ +#define INFO_MASTER_CLIENT 0x01 +#define INFO_IO_CLIENT 0x02 +#define INFO_MTD_CLIENT 0x04 +#define INFO_MEM_CLIENT 0x08 +#define MAX_NUM_CLIENTS 3 + +#define INFO_CARD_SHARE 0x10 +#define INFO_CARD_EXCL 0x20 + +typedef struct cs_status_t { + u_char Function; + event_t CardState; + event_t SocketState; +} cs_status_t; + +typedef struct error_info_t { + int func; + int retcode; +} error_info_t; + +/* Special stuff for binding drivers to sockets */ +typedef struct bind_req_t { + socket_t Socket; + u_char Function; + dev_info_t *dev_info; +} bind_req_t; + +/* Flag to bind to all functions */ +#define BIND_FN_ALL 0xff + +typedef struct mtd_bind_t { + socket_t Socket; + u_int Attributes; + u_int CardOffset; + dev_info_t *dev_info; +} mtd_bind_t; + +/* Events */ +#define CS_EVENT_PRI_LOW 0 +#define CS_EVENT_PRI_HIGH 1 + +#define CS_EVENT_WRITE_PROTECT 0x000001 +#define CS_EVENT_CARD_LOCK 0x000002 +#define CS_EVENT_CARD_INSERTION 0x000004 +#define CS_EVENT_CARD_REMOVAL 0x000008 +#define CS_EVENT_BATTERY_DEAD 0x000010 +#define CS_EVENT_BATTERY_LOW 0x000020 +#define CS_EVENT_READY_CHANGE 0x000040 +#define CS_EVENT_CARD_DETECT 0x000080 +#define CS_EVENT_RESET_REQUEST 0x000100 +#define CS_EVENT_RESET_PHYSICAL 0x000200 +#define CS_EVENT_CARD_RESET 0x000400 +#define CS_EVENT_REGISTRATION_COMPLETE 0x000800 +#define CS_EVENT_RESET_COMPLETE 0x001000 +#define CS_EVENT_PM_SUSPEND 0x002000 +#define CS_EVENT_PM_RESUME 0x004000 +#define CS_EVENT_INSERTION_REQUEST 0x008000 +#define CS_EVENT_EJECTION_REQUEST 0x010000 +#define CS_EVENT_MTD_REQUEST 0x020000 +#define CS_EVENT_ERASE_COMPLETE 0x040000 +#define CS_EVENT_REQUEST_ATTENTION 0x080000 +#define CS_EVENT_CB_DETECT 0x100000 +#define CS_EVENT_3VCARD 0x200000 +#define CS_EVENT_XVCARD 0x400000 + +/* Return codes */ +#define CS_SUCCESS 0x00 +#define CS_BAD_ADAPTER 0x01 +#define CS_BAD_ATTRIBUTE 0x02 +#define CS_BAD_BASE 0x03 +#define CS_BAD_EDC 0x04 +#define CS_BAD_IRQ 0x06 +#define CS_BAD_OFFSET 0x07 +#define CS_BAD_PAGE 0x08 +#define CS_READ_FAILURE 0x09 +#define CS_BAD_SIZE 0x0a +#define CS_BAD_SOCKET 0x0b +#define CS_BAD_TYPE 0x0d +#define CS_BAD_VCC 0x0e +#define CS_BAD_VPP 0x0f +#define CS_BAD_WINDOW 0x11 +#define CS_WRITE_FAILURE 0x12 +#define CS_NO_CARD 0x14 +#define CS_UNSUPPORTED_FUNCTION 0x15 +#define CS_UNSUPPORTED_MODE 0x16 +#define CS_BAD_SPEED 0x17 +#define CS_BUSY 0x18 +#define CS_GENERAL_FAILURE 0x19 +#define CS_WRITE_PROTECTED 0x1a +#define CS_BAD_ARG_LENGTH 0x1b +#define CS_BAD_ARGS 0x1c +#define CS_CONFIGURATION_LOCKED 0x1d +#define CS_IN_USE 0x1e +#define CS_NO_MORE_ITEMS 0x1f +#define CS_OUT_OF_RESOURCE 0x20 +#define CS_BAD_HANDLE 0x21 + +#define CS_BAD_TUPLE 0x40 + +#ifdef __KERNEL__ + +/* + * Calls to set up low-level "Socket Services" drivers + */ + +typedef int (*ss_entry_t)(u_int sock, u_int cmd, void *arg); +extern int register_ss_entry(int nsock, ss_entry_t entry); +extern void unregister_ss_entry(ss_entry_t entry); + +/* + * The main Card Services entry point + */ + +enum service { + AccessConfigurationRegister, AddSocketServices, + AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory, + DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo, + GetClientInfo, GetConfigurationInfo, GetEventMask, + GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple, + GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple, + GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage, + MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow, + OpenMemory, ParseTuple, ReadMemory, RegisterClient, + RegisterEraseQueue, RegisterMTD, RegisterTimer, + ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ, + ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices, + RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ, + RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry, + SetEventMask, SetRegion, ValidateCIS, VendorSpecific, + WriteMemory, BindDevice, BindMTD, ReportError, + SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS, + GetFirstWindow, GetNextWindow, GetMemPage +}; + +#ifdef IN_CARD_SERVICES +extern int CardServices(int func, void *a1, void *a2, void *a3); +#else +extern int CardServices(int func, ...); +#endif + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_CS_H */ diff --git a/headers/os/drivers/pcmcia/cs_types.h b/headers/os/drivers/pcmcia/cs_types.h new file mode 100644 index 0000000000..88471f98e0 --- /dev/null +++ b/headers/os/drivers/pcmcia/cs_types.h @@ -0,0 +1,70 @@ +/* + * cs_types.h 1.20 2002/04/17 02:52:39 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef _LINUX_CS_TYPES_H +#define _LINUX_CS_TYPES_H + +#ifdef __linux__ +#ifdef __KERNEL__ +#include +#else +#include +#endif +#endif + +#ifdef __arm__ +typedef u_int ioaddr_t; +#else +typedef u_short ioaddr_t; +#endif + +typedef u_short socket_t; +typedef u_int event_t; +typedef u_char cisdata_t; +typedef u_short page_t; + +struct client_t; +typedef struct client_t *client_handle_t; + +struct window_t; +typedef struct window_t *window_handle_t; + +struct region_t; +typedef struct region_t *memory_handle_t; + +struct eraseq_t; +typedef struct eraseq_t *eraseq_handle_t; + +#ifndef DEV_NAME_LEN +#define DEV_NAME_LEN 32 +#endif + +typedef char dev_info_t[DEV_NAME_LEN]; + +#endif /* _LINUX_CS_TYPES_H */ diff --git a/headers/os/drivers/pcmcia/driver_ops.h b/headers/os/drivers/pcmcia/driver_ops.h new file mode 100644 index 0000000000..9903e5bf54 --- /dev/null +++ b/headers/os/drivers/pcmcia/driver_ops.h @@ -0,0 +1,73 @@ +/* + * driver_ops.h 1.17 2001/10/04 03:15:22 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef _LINUX_DRIVER_OPS_H +#define _LINUX_DRIVER_OPS_H + +#ifndef DEV_NAME_LEN +#define DEV_NAME_LEN 32 +#endif + +#ifdef __KERNEL__ + +typedef struct dev_node_t { + char dev_name[DEV_NAME_LEN]; + u_short major, minor; + struct dev_node_t *next; +} dev_node_t; + +typedef struct dev_locator_t { + enum { LOC_ISA, LOC_PCI } bus; + union { + struct { + u_short io_base_1, io_base_2; + u_long mem_base; + u_char irq, dma; + } isa; + struct { + u_char bus; + u_char devfn; + } pci; + } b; +} dev_locator_t; + +typedef struct driver_operations { + char *name; + dev_node_t *(*attach) (dev_locator_t *loc); + void (*suspend) (dev_node_t *dev); + void (*resume) (dev_node_t *dev); + void (*detach) (dev_node_t *dev); +} driver_operations; + +int register_driver(struct driver_operations *ops); +void unregister_driver(struct driver_operations *ops); + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_DRIVER_OPS_H */ diff --git a/headers/os/drivers/pcmcia/ds.h b/headers/os/drivers/pcmcia/ds.h new file mode 100644 index 0000000000..9d72d62dda --- /dev/null +++ b/headers/os/drivers/pcmcia/ds.h @@ -0,0 +1,160 @@ +/* + * ds.h 1.58 2001/10/04 03:15:22 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef _LINUX_DS_H +#define _LINUX_DS_H + +#include +#include + +typedef struct tuple_parse_t { + tuple_t tuple; + cisdata_t data[255]; + cisparse_t parse; +} tuple_parse_t; + +typedef struct win_info_t { + window_handle_t handle; + win_req_t window; + memreq_t map; +} win_info_t; + +typedef struct bind_info_t { + dev_info_t dev_info; + u_char function; + struct dev_link_t *instance; + char name[DEV_NAME_LEN]; + u_short major, minor; + void *next; +} bind_info_t; + +typedef struct mtd_info_t { + dev_info_t dev_info; + u_int Attributes; + u_int CardOffset; +} mtd_info_t; + +typedef union ds_ioctl_arg_t { + servinfo_t servinfo; + adjust_t adjust; + config_info_t config; + tuple_t tuple; + tuple_parse_t tuple_parse; + client_req_t client_req; + cs_status_t status; + conf_reg_t conf_reg; + cisinfo_t cisinfo; + region_info_t region; + bind_info_t bind_info; + mtd_info_t mtd_info; + win_info_t win_info; + cisdump_t cisdump; +} ds_ioctl_arg_t; + +#ifndef __HAIKU__ +#undef _IOC +#undef _IOR +#undef _IOW +#undef _IOWR +#define _IOC(inout, group, num, len) \ + (inout | ((len & IOCPARM_MASK)<<2) | ((group) << 24) | (num<<16)) +#define _IOR(g,n,t) _IOC(2, (g), (n), sizeof(t)) +#define _IOW(g,n,t) _IOC(1 , (g), (n), sizeof(t)) +#define _IOWR(g,n,t) _IOC(3, (g), (n), sizeof(t)) +#endif + +#define DS_GET_CARD_SERVICES_INFO _IOR ('d', 1, servinfo_t) +#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t) +#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t) +#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t) +#define DS_GET_NEXT_TUPLE _IOWR('d', 5, tuple_t) +#define DS_GET_TUPLE_DATA _IOWR('d', 6, tuple_parse_t) +#define DS_PARSE_TUPLE _IOWR('d', 7, tuple_parse_t) +#define DS_RESET_CARD _IO ('d', 8) +#define DS_GET_STATUS _IOWR('d', 9, cs_status_t) +#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t) +#define DS_VALIDATE_CIS _IOR ('d', 11, cisinfo_t) +#define DS_SUSPEND_CARD _IO ('d', 12) +#define DS_RESUME_CARD _IO ('d', 13) +#define DS_EJECT_CARD _IO ('d', 14) +#define DS_INSERT_CARD _IO ('d', 15) +#define DS_GET_FIRST_REGION _IOWR('d', 16, region_info_t) +#define DS_GET_NEXT_REGION _IOWR('d', 17, region_info_t) +#define DS_REPLACE_CIS _IOWR('d', 18, cisdump_t) +#define DS_GET_FIRST_WINDOW _IOR ('d', 19, win_info_t) +#define DS_GET_NEXT_WINDOW _IOWR('d', 20, win_info_t) +#define DS_GET_MEM_PAGE _IOWR('d', 21, win_info_t) + +#define DS_BIND_REQUEST _IOWR('d', 60, bind_info_t) +#define DS_GET_DEVICE_INFO _IOWR('d', 61, bind_info_t) +#define DS_GET_NEXT_DEVICE _IOWR('d', 62, bind_info_t) +#define DS_UNBIND_REQUEST _IOW ('d', 63, bind_info_t) +#define DS_BIND_MTD _IOWR('d', 64, mtd_info_t) + +#ifdef __KERNEL__ + +typedef struct dev_link_t { + dev_node_t *dev; + u_int state, open; + wait_queue_head_t pending; + struct timer_list release; + client_handle_t handle; + io_req_t io; + irq_req_t irq; + config_req_t conf; + window_handle_t win; + void *priv; + struct dev_link_t *next; +} dev_link_t; + +/* Flags for device state */ +#define DEV_PRESENT 0x01 +#define DEV_CONFIG 0x02 +#define DEV_STALE_CONFIG 0x04 /* release on close */ +#define DEV_STALE_LINK 0x08 /* detach on release */ +#define DEV_CONFIG_PENDING 0x10 +#define DEV_RELEASE_PENDING 0x20 +#define DEV_SUSPEND 0x40 +#define DEV_BUSY 0x80 + +#define DEV_OK(l) \ + ((l) && ((l->state & ~DEV_BUSY) == (DEV_CONFIG|DEV_PRESENT))) + +int register_pccard_driver(dev_info_t *dev_info, + dev_link_t *(*attach)(void), + void (*detach)(dev_link_t *)); + +int unregister_pccard_driver(dev_info_t *dev_info); + +#define register_pcmcia_driver register_pccard_driver +#define unregister_pcmcia_driver unregister_pccard_driver + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_DS_H */ diff --git a/headers/os/drivers/pcmcia/ftl.h b/headers/os/drivers/pcmcia/ftl.h new file mode 100644 index 0000000000..f5f13bbe05 --- /dev/null +++ b/headers/os/drivers/pcmcia/ftl.h @@ -0,0 +1,62 @@ +/* + * ftl.h 1.5 1999/07/20 16:07:58 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1998 David A. Hinds. All Rights Reserved. + */ + +#ifndef _LINUX_FTL_H +#define _LINUX_FTL_H + +typedef struct erase_unit_header_t { + u_char LinkTargetTuple[5]; + u_char DataOrgTuple[10]; + u_char NumTransferUnits; + u_int EraseCount; + u_short LogicalEUN; + u_char BlockSize; + u_char EraseUnitSize; + u_short FirstPhysicalEUN; + u_short NumEraseUnits; + u_int FormattedSize; + u_int FirstVMAddress; + u_short NumVMPages; + u_char Flags; + u_char Code; + u_int SerialNumber; + u_int AltEUHOffset; + u_int BAMOffset; + u_char Reserved[12]; + u_char EndTuple[2]; +} erase_unit_header_t; + +/* Flags in erase_unit_header_t */ +#define HIDDEN_AREA 0x01 +#define REVERSE_POLARITY 0x02 +#define DOUBLE_BAI 0x04 + +/* Definitions for block allocation information */ + +#define BLOCK_FREE(b) ((b) == 0xffffffff) +#define BLOCK_DELETED(b) (((b) == 0) || ((b) == 0xfffffffe)) + +#define BLOCK_TYPE(b) ((b) & 0x7f) +#define BLOCK_ADDRESS(b) ((b) & ~0x7f) +#define BLOCK_NUMBER(b) ((b) >> 9) +#define BLOCK_CONTROL 0x30 +#define BLOCK_DATA 0x40 +#define BLOCK_REPLACEMENT 0x60 +#define BLOCK_BAD 0x70 + +#endif /* _LINUX_FTL_H */ diff --git a/headers/os/drivers/pcmcia/ss.h b/headers/os/drivers/pcmcia/ss.h new file mode 100644 index 0000000000..e4c68da3d4 --- /dev/null +++ b/headers/os/drivers/pcmcia/ss.h @@ -0,0 +1,119 @@ +/* + * ss.h 1.23 1999/07/20 16:08:01 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * . Portions created by David A. Hinds + * are Copyright (C) 1998 David A. Hinds. All Rights Reserved. + */ + +#ifndef _LINUX_SS_H +#define _LINUX_SS_H + +/* For RegisterCallback */ +typedef struct ss_callback_t { + void (*handler)(void *info, u_int events); + void *info; +} ss_callback_t; + +/* Definitions for card status flags for GetStatus */ +#define SS_WRPROT 0x0001 +#define SS_CARDLOCK 0x0002 +#define SS_EJECTION 0x0004 +#define SS_INSERTION 0x0008 +#define SS_BATDEAD 0x0010 +#define SS_BATWARN 0x0020 +#define SS_READY 0x0040 +#define SS_DETECT 0x0080 +#define SS_POWERON 0x0100 +#define SS_GPI 0x0200 +#define SS_STSCHG 0x0400 +#define SS_CARDBUS 0x0800 +#define SS_3VCARD 0x1000 +#define SS_XVCARD 0x2000 + +/* for InquireSocket */ +typedef struct socket_cap_t { + u_int features; + u_int irq_mask; + u_int map_size; + u_char pci_irq; + u_char cardbus; + struct pci_bus *cb_bus; + struct bus_operations *bus; +} socket_cap_t; + +/* InquireSocket capabilities */ +#define SS_CAP_PAGE_REGS 0x0001 +#define SS_CAP_VIRTUAL_BUS 0x0002 +#define SS_CAP_MEM_ALIGN 0x0004 +#define SS_CAP_PCCARD 0x4000 +#define SS_CAP_CARDBUS 0x8000 + +/* for GetSocket, SetSocket */ +typedef struct socket_state_t { + u_int flags; + u_int csc_mask; + u_char Vcc, Vpp; + u_char io_irq; +} socket_state_t; + +/* Socket configuration flags */ +#define SS_PWR_AUTO 0x0010 +#define SS_IOCARD 0x0020 +#define SS_RESET 0x0040 +#define SS_DMA_MODE 0x0080 +#define SS_SPKR_ENA 0x0100 +#define SS_OUTPUT_ENA 0x0200 + +/* Flags for I/O port and memory windows */ +#define MAP_ACTIVE 0x01 +#define MAP_16BIT 0x02 +#define MAP_AUTOSZ 0x04 +#define MAP_0WS 0x08 +#define MAP_WRPROT 0x10 +#define MAP_ATTRIB 0x20 +#define MAP_USE_WAIT 0x40 +#define MAP_PREFETCH 0x80 + +/* Use this just for bridge windows */ +#define MAP_IOSPACE 0x20 + +typedef struct pccard_io_map { + u_char map; + u_char flags; + u_short speed; + u_short start, stop; +} pccard_io_map; + +typedef struct pccard_mem_map { + u_char map; + u_char flags; + u_short speed; + u_long sys_start, sys_stop; + u_int card_start; +} pccard_mem_map; + +typedef struct cb_bridge_map { + u_char map; + u_char flags; + u_int start, stop; +} cb_bridge_map; + +enum ss_service { + SS_RegisterCallback, SS_InquireSocket, + SS_GetStatus, SS_GetSocket, SS_SetSocket, + SS_GetIOMap, SS_SetIOMap, SS_GetMemMap, SS_SetMemMap, + SS_GetBridge, SS_SetBridge, SS_ProcSetup +}; + +#endif /* _LINUX_SS_H */ diff --git a/headers/os/drivers/pcmcia/version.h b/headers/os/drivers/pcmcia/version.h new file mode 100644 index 0000000000..7f67ee78bf --- /dev/null +++ b/headers/os/drivers/pcmcia/version.h @@ -0,0 +1,13 @@ +/* version.h 1.118 2003/12/20 07:16:36 (David Hinds) */ + +#define CS_PKG_RELEASE "3.2.8" +#define CS_PKG_RELEASE_CODE 0x3208 + +#define VERSION(v,p,s) (((v)<<16)+(p<<8)+s) + +#ifdef CONFIG_PCMCIA +#include_next +#else +#define CS_RELEASE CS_PKG_RELEASE +#define CS_RELEASE_CODE CS_PKG_RELEASE_CODE +#endif diff --git a/src/bin/pcmcia-cs/Jamfile b/src/bin/pcmcia-cs/Jamfile new file mode 100644 index 0000000000..441b4274db --- /dev/null +++ b/src/bin/pcmcia-cs/Jamfile @@ -0,0 +1,7 @@ +SubDir OBOS_TOP src bin pcmcia-cs ; + +StdBinCommands + cardctl.c + dump_cis.c + dump_cisreg.c + : libroot.so ; diff --git a/src/bin/pcmcia-cs/cardctl.8 b/src/bin/pcmcia-cs/cardctl.8 new file mode 100644 index 0000000000..bb1030742f --- /dev/null +++ b/src/bin/pcmcia-cs/cardctl.8 @@ -0,0 +1,97 @@ +.\" Copyright (C) 1998 David A. Hinds -- dahinds@users.sourceforge.net +.\" cardctl.8 1.18 2002/08/19 03:08:44 +.\" +.TH CARDCTL 8 "2002/08/19 03:08:44" "pcmcia-cs" +.SH NAME +cardctl \- PCMCIA card control utility + +.SH SYNOPSIS +\fBcardctl\fR [\fB-V\fR] \fIcommand\fR [\fIsocket\fR] +.br +\fBcardctl\fR +[\fB\-c \fIconfig\fR] [\fB\-f \fIscheme\fR] [\fB\-s \fIstab\fR] +\fBscheme\fR [\fIname\fR] + +.SH DESCRIPTION +\fBCardctl\fR is used to monitor and control the state of PCMCIA +sockets. If a socket number is specified, the command will be applied +to just one socket; otherwise, all sockets will be affected. +.PP +\fBCardctl\fR is also used to select between multiple PCMCIA +configuration schemes. The current scheme name is passed to the +device option scripts as part of the ``device address'', so the +scripts can use it to choose between different setups. +.PP +If \fBcardctl\fR is executed by root, all commands are available. If +it is executed by an unpriviledged user, only the informational +commands are accessible. +.PP +Some commands may not work or give misleading results if \fBcardmgr\fR +is not running. + +.SH COMMANDS +.TP \w'abcd'u +.B status +Display the current socket status flags. +.TP +.B config +Display the socket configuration, including power settings, interrupt +and I/O window settings, and configuration registers. +.TP +.B ident +Display card identification information, including product +identification strings, manufacturer ID codes, and function ID codes. +.TP +.B info +Much like the \fBident\fR command, but its output is formatted as a +series of Bourne-stype shell variable definitions for use in scripts. +.TP +.B suspend +Shut down and then disable power for a socket. +.TP +.B resume +Restore power to a socket, and re-configure for use. +.TP +.B reset +Send a reset signal to a socket, subject to approval by any drivers +already bound to the socket. +.TP +.B eject +Notify all client drivers that this card will be ejected, then cut +power to the socket. +.TP +.B insert +Notify all client drivers that this card has just been inserted. +.TP +.B scheme +If no scheme name is given, +.B cardctl +will display the current PCMCIA configuration scheme. If a scheme +name is given, +.B cardctl +will unconfigure all PCMCIA devices, and reconfigure for the new +scheme. + +.SH OPTIONS +.TP +.B \-V +Show version information and exit. +.TP +.BI "\-c " config +Look for the card configuration database and card configuration +scripts in the specified directory, instead of +.IR /etc/pcmcia . +.TP +.BI "\-f " scheme +Use the specified file to keep track of the current configuration +scheme, instead of +.IR /var/lib/pcmcia/scheme . +.TP +.BI "\-s " stab +Read current socket information from the specified file, instead of +.IR /var/lib/pcmcia/stab . + +.SH AUTHOR +David Hinds \- dahinds@users.sourceforge.net +.SH "SEE ALSO" +cardmgr(8). diff --git a/src/bin/pcmcia-cs/cardctl.c b/src/bin/pcmcia-cs/cardctl.c new file mode 100644 index 0000000000..24ecf0c8b1 --- /dev/null +++ b/src/bin/pcmcia-cs/cardctl.c @@ -0,0 +1,765 @@ +/*====================================================================== + + PCMCIA device control program + + cardctl.c 1.70 2004/04/09 03:54:53 + + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + + Alternatively, the contents of this file may be used under the + terms of the GNU General Public License version 2 (the "GPL"), in + which case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + +======================================================================*/ +#ifdef __BEOS__ +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/*====================================================================*/ + +#ifdef ETC +static char *configpath = ETC; +#else +static char *configpath = "/etc/pcmcia"; +#endif + +static char *scheme, *stabfile; + +/*====================================================================*/ +#ifndef __BEOS__ +static int major = 0; + +static int lookup_dev(char *name) +{ + FILE *f; + int n; + char s[32], t[32]; + + f = fopen("/proc/devices", "r"); + if (f == NULL) + return -errno; + while (fgets(s, 32, f) != NULL) { + if (sscanf(s, "%d %s", &n, t) == 2) + if (strcmp(name, t) == 0) + break; + } + fclose(f); + if (strcmp(name, t) == 0) + return n; + else + return -ENODEV; +} /* lookup_dev */ +#endif + +/*====================================================================*/ + +static int open_sock(int sock) +{ +#ifdef __BEOS__ + char fn[B_OS_NAME_LENGTH]; + sprintf(fn, "/dev/bus/pcmcia/sock/%d", sock); + return open(fn, O_RDONLY); +#else + static char *paths[] = { + "/var/lib/pcmcia", "/var/run", "/dev", "/tmp", NULL + }; + int fd; + char **p, fn[64]; + dev_t dev = makedev(major, sock); + + for (p = paths; *p; p++) { + sprintf(fn, "%s/cc-%d", *p, getpid()); + if (mknod(fn, (S_IFCHR|S_IREAD|S_IWRITE), dev) == 0) { + fd = open(fn, O_RDONLY); + unlink(fn); + if (fd >= 0) + return fd; + if (errno == ENODEV) + break; + } + } + return -1; +#endif +} /* open_sock */ + +/*====================================================================*/ + +static void print_status(cs_status_t *status) +{ + char *v = "5"; + if (status->Function == 0) { + printf(" "); + if (status->CardState & CS_EVENT_3VCARD) + v = "3.3"; + else if (status->CardState & CS_EVENT_XVCARD) + v = "X.X"; + if (status->CardState & CS_EVENT_CB_DETECT) + printf("%sV CardBus card", v); + else if (status->CardState & CS_EVENT_CARD_DETECT) + printf("%sV 16-bit PC Card", v); + else + printf("no card"); + if (status->CardState & CS_EVENT_PM_SUSPEND) + printf(" [suspended]"); + printf("\n"); + } + if ((status->CardState & CS_EVENT_PM_SUSPEND) || + !(status->CardState & CS_EVENT_CARD_DETECT)) + return; + printf(" function %d: ", status->Function); + printf("%s", (status->CardState & CS_EVENT_READY_CHANGE) + ? "[ready]" : "[busy]"); + if (status->CardState & CS_EVENT_WRITE_PROTECT) + printf(", [wp]"); + if (status->CardState & CS_EVENT_BATTERY_DEAD) + printf(", [bat dead]"); + if (status->CardState & CS_EVENT_BATTERY_LOW) + printf(", [bat low]"); + if (status->CardState & CS_EVENT_REQUEST_ATTENTION) + printf(", [req attn]"); + printf("\n"); +} /* print_status */ + +/*====================================================================*/ + +static void print_config(config_info_t *config) +{ + if (config->Function == 0) { + printf(" Vcc %.1fV Vpp1 %.1fV Vpp2 %.1fV\n", + config->Vcc/10.0, config->Vpp1/10.0, config->Vpp2/10.0); + if (!(config->Attributes & CONF_VALID_CLIENT)) + return; + printf(" interface type is "); + switch (config->IntType) { + case INT_MEMORY: + printf("\"memory-only\"\n"); break; + case INT_MEMORY_AND_IO: + printf("\"memory and I/O\"\n"); break; + case INT_CARDBUS: + printf("\"cardbus\"\n"); break; + } + if (config->AssignedIRQ != 0) { + printf(" irq %d", config->AssignedIRQ); + switch (config->IRQAttributes & IRQ_TYPE) { + case IRQ_TYPE_EXCLUSIVE: + printf(" [exclusive]"); break; + case IRQ_TYPE_TIME: + printf(" [multiplexed]"); break; + case IRQ_TYPE_DYNAMIC_SHARING: + printf(" [shared]"); break; + } + if (config->IRQAttributes & IRQ_PULSE_ALLOCATED) + printf(" [pulse]"); + else + printf(" [level]"); + if (!(config->Attributes & CONF_ENABLE_IRQ)) + printf(" [disabled]"); + printf("\n"); + } + if (config->Attributes & CONF_ENABLE_DMA) + printf(" DMA mode is enabled\n"); + if (config->Attributes & CONF_ENABLE_SPKR) + printf(" speaker output is enabled\n"); + + } + + if (!(config->Attributes & CONF_VALID_CLIENT)) + return; + + printf(" function %d:\n", config->Function); + + if (config->CardValues) { + printf(" config base %#06x\n", config->ConfigBase); + printf(" "); + if (config->CardValues & CV_OPTION_VALUE) + printf(" option 0x%02x", config->Option); + if (config->CardValues & CV_STATUS_VALUE) + printf(" status 0x%02x", config->Status); + if (config->CardValues & CV_PIN_REPLACEMENT) + printf(" pin 0x%02x", config->Pin); + if (config->CardValues & CV_COPY_VALUE) + printf(" copy 0x%02x", config->Copy); + if (config->CardValues & CV_EXT_STATUS) + printf(" ext 0x%02x", config->ExtStatus); + printf("\n"); + } + + if (config->NumPorts1 > 0) { + printf(" io %#06x-%#06x", config->BasePort1, + config->BasePort1 + config->NumPorts1 - 1); + if (config->IntType == INT_CARDBUS) { + printf(" [32bit]\n"); + } else { + if (config->Attributes1 & IO_SHARED) + printf(" [shared]"); + if (config->Attributes1 & IO_FORCE_ALIAS_ACCESS) + printf(" [alias]"); + switch (config->Attributes1 & IO_DATA_PATH_WIDTH) { + case IO_DATA_PATH_WIDTH_8: + printf(" [8bit]\n"); break; + case IO_DATA_PATH_WIDTH_16: + printf(" [16bit]\n"); break; + case IO_DATA_PATH_WIDTH_AUTO: + printf(" [auto]\n"); break; + } + } + } + if (config->NumPorts2 > 0) { + printf(" io %#06x-%#06x", config->BasePort2, + config->BasePort2 + config->NumPorts2 - 1); + if (config->Attributes2 & IO_SHARED) + printf(" [shared]"); + if (config->Attributes2 & IO_FORCE_ALIAS_ACCESS) + printf(" [alias]"); + switch (config->Attributes2 & IO_DATA_PATH_WIDTH) { + case IO_DATA_PATH_WIDTH_8: + printf(" [8bit]\n"); break; + case IO_DATA_PATH_WIDTH_16: + printf(" [16bit]\n"); break; + case IO_DATA_PATH_WIDTH_AUTO: + printf(" [auto]\n"); break; + } + } +} /* print_config */ + +/*====================================================================*/ + +static void print_windows(int fd) +{ + ds_ioctl_arg_t arg1, arg2; + int ret; + win_req_t *win = &arg1.win_info.window; + memreq_t *req = &arg2.win_info.map; + + ret = ioctl(fd, DS_GET_FIRST_WINDOW, &arg1); + while (ret == 0) { + arg2.win_info.handle = arg1.win_info.handle; + ioctl(fd, DS_GET_MEM_PAGE, &arg2); + printf(" memory 0x%04x-0x%04x @ 0x%08lx", + req->CardOffset, req->CardOffset+win->Size-1, + win->Base); + if (win->Attributes & WIN_MEMORY_TYPE_AM) + printf(" [attr]"); + if (!(win->Attributes & WIN_ENABLE)) + printf(" [disabled]"); + if (win->Attributes & WIN_USE_WAIT) + printf(" [wait]"); + switch (win->Attributes & WIN_DATA_WIDTH) { + case WIN_DATA_WIDTH_8: + printf(" [8bit]\n"); break; + case WIN_DATA_WIDTH_16: + printf(" [16bit]\n"); break; + case WIN_DATA_WIDTH_32: + printf(" [32bit]\n"); break; + } + ret = ioctl(fd, DS_GET_NEXT_WINDOW, &arg1); + } +} + +/*====================================================================*/ + +static int get_tuple(int fd, cisdata_t code, ds_ioctl_arg_t *arg) +{ + arg->tuple.DesiredTuple = code; + arg->tuple.Attributes = TUPLE_RETURN_COMMON; + arg->tuple.TupleOffset = 0; + if ((ioctl(fd, DS_GET_FIRST_TUPLE, arg) == 0) && + (ioctl(fd, DS_GET_TUPLE_DATA, arg) == 0) && + (ioctl(fd, DS_PARSE_TUPLE, arg) == 0)) + return 0; + else + return -1; +} + +static void print_ident(int fd) +{ + ds_ioctl_arg_t arg; + cistpl_vers_1_t *vers = &arg.tuple_parse.parse.version_1; + cistpl_manfid_t *manfid = &arg.tuple_parse.parse.manfid; + cistpl_funcid_t *funcid = &arg.tuple_parse.parse.funcid; + config_info_t config; + int i; + static char *fn[] = { + "multifunction", "memory", "serial", "parallel", + "fixed disk", "video", "network", "AIMS", "SCSI" + }; + + if (get_tuple(fd, CISTPL_VERS_1, &arg) == 0) { + printf(" product info: "); + for (i = 0; i < vers->ns; i++) + printf("%s\"%s\"", (i>0) ? ", " : "", + vers->str+vers->ofs[i]); + printf("\n"); + } else { + printf(" no product info available\n"); + } + if (get_tuple(fd, CISTPL_MANFID, &arg) == 0) + printf(" manfid: 0x%04x, 0x%04x\n", + manfid->manf, manfid->card); + if (get_tuple(fd, CISTPL_FUNCID, &arg) == 0) + printf(" function: %d (%s)\n", funcid->func, + fn[funcid->func]); + config.Function = config.ConfigBase = 0; + if ((ioctl(fd, DS_GET_CONFIGURATION_INFO, &config) == 0) && + (config.IntType == INT_CARDBUS) && config.ConfigBase) + printf(" PCI id: 0x%04x, 0x%04x\n", + config.ConfigBase & 0xffff, + config.ConfigBase >> 16); +} + +static void print_info(int fd) +{ + ds_ioctl_arg_t arg; + cistpl_vers_1_t *vers = &arg.tuple_parse.parse.version_1; + cistpl_manfid_t *manfid = &arg.tuple_parse.parse.manfid; + cistpl_funcid_t *funcid = &arg.tuple_parse.parse.funcid; + config_info_t config; + int i; + + vers->ns = 0; + get_tuple(fd, CISTPL_VERS_1, &arg); + for (i = 0; i < 4; i++) + printf("PRODID_%d=\"%s\"\n", i+1, + (i < vers->ns) ? vers->str+vers->ofs[i] : ""); + *manfid = (cistpl_manfid_t) { 0, 0 }; + get_tuple(fd, CISTPL_MANFID, &arg); + printf("MANFID=%04x,%04x\n", manfid->manf, manfid->card); + *funcid = (cistpl_funcid_t) { 0xff, 0xff }; + get_tuple(fd, CISTPL_FUNCID, &arg); + printf("FUNCID=%d\n", funcid->func); + config.Function = config.ConfigBase = 0; +} + +/*====================================================================*/ + +typedef enum cmd_t { + C_STATUS, C_CONFIG, C_IDENT, C_INFO, C_SUSPEND, + C_RESUME, C_RESET, C_EJECT, C_INSERT +} cmd_t; + +static char *cmdname[] = { + "status", "config", "ident", "info", "suspend", + "resume", "reset", "eject", "insert" +}; + +#define NCMD (sizeof(cmdname)/sizeof(char *)) + +static int do_cmd(int fd, int cmd) +{ + int i, ret; + cs_status_t status; + config_info_t config; + + ret = 0; + switch (cmd) { + + case C_STATUS: + for (i = 0; i < 4; i++) { + status.Function = i; + if (ioctl(fd, DS_GET_STATUS, &status) == 0) + print_status(&status); + else { + if (i == 0) { + if (errno == ENODEV) + printf(" no card\n"); + else + perror("ioctl()"); + } + break; + } + } + break; + + case C_CONFIG: + for (i = 0; i < 4; i++) { + config.Function = i; + if (ioctl(fd, DS_GET_CONFIGURATION_INFO, &config) == 0) + print_config(&config); + else { + if (i == 0) printf(" not configured\n"); + break; + } + print_windows(fd); + } + break; + + case C_IDENT: + print_ident(fd); + break; + + case C_INFO: + print_info(fd); + break; + + case C_SUSPEND: + ret = ioctl(fd, DS_SUSPEND_CARD); + break; + + case C_RESUME: + ret = ioctl(fd, DS_RESUME_CARD); + break; + + case C_RESET: + ret = ioctl(fd, DS_RESET_CARD); + break; + + case C_EJECT: + ret = ioctl(fd, DS_EJECT_CARD); + break; + + case C_INSERT: + ret = ioctl(fd, DS_INSERT_CARD); + break; + } + return ret; +} + +/*====================================================================== + + A utility function to scan /var/run/stab and apply a specified action + to each device, in turn. If any command returns a non-zero exit + code, execute() returns -1. + +======================================================================*/ + +typedef struct stab_t { + int socket, instance, status; + char class[33], driver[33], dev[33]; +} stab_t; + +static stab_t stab[256]; +static int nstab; + +static int fetch_stab(void) +{ + char s[133]; + FILE *f; + + f = fopen(stabfile, "r"); + if (f == NULL) + return -1; + for (nstab = 0; fgets(s, 132, f); ) { + if (s[0] != 'S') { + sscanf(s, "%d\t%s\t%s\t%d\t%s", + &stab[nstab].socket, stab[nstab].class, + stab[nstab].driver, &stab[nstab].instance, + stab[nstab].dev); + stab[nstab].status = 0; + nstab++; + } + } + fclose(f); + return 0; +} + +#ifndef __BEOS__ +static void eprintf(char *name, char *fmt, ...) +{ + va_list args; + char s[32]; + va_start(args, fmt); + vsprintf(s, fmt, args); + setenv(name, s, 1); + va_end(args); +} +#endif + +static int execute(stab_t *s, char *action, char *scheme) +{ + int ret; + char cmd[133]; + +#ifndef __BEOS__ + eprintf("SOCKET", "%d", s->socket); + eprintf("INSTANCE", "%d", s->instance); +#endif + if (scheme) + sprintf(cmd, "./%s %s %s %s", s->class, action, s->dev, scheme); + else + sprintf(cmd, "./%s %s %s", s->class, action, s->dev); + ret = system(cmd); + if (!WIFEXITED(ret) || WEXITSTATUS(ret)) + return -1; + return 0; +} + +static int stop_scheme(char *new) +{ + int i; + + fprintf(stderr, "checking:"); + for (i = 0; i < nstab; i++) { + fprintf(stderr, " %s", stab[i].dev); + stab[i].status = execute(stab+i, "cksum", new); + if (stab[i].status && + (execute(stab+i, "check", NULL) != 0)) break; + } + fprintf(stderr, "\n"); + if (i < nstab) { + fprintf(stderr, "Device '%s' busy: scheme unchanged.\n", + stab[i].dev); + return -1; + } + for (i = 0; i < nstab; i++) + if (stab[i].status) execute(stab+i, "stop", NULL); + return 0; +} + +static int start_scheme(void) +{ + int i, j = 0; + + for (i = 0; i < nstab; i++) + if (stab[i].status) j |= execute(stab+i, "start", NULL); + return j; +} + +/*====================================================================== + + do_scheme() is in charge of checking and updating the current + PCMCIA configuration scheme. The current scheme is kept in a + file, /var/run/pcmcia-scheme. When updating the scheme, we first + stop all PCMCIA devices, then update the scheme, then restart. + +======================================================================*/ + +static int do_scheme(char *new) +{ + FILE *f; + char old[33]; + int i; + + f = fopen(scheme, "r"); + if (f && fgets(old, 32, f)) + old[strlen(old)-1] = '\0'; + else + old[0] = '\0'; + if (f) fclose(f); + + if (new) { + +#ifndef UNSAFE_TOOLS + if (getuid() != 0) { + fprintf(stderr, "Only root can select a new scheme.\n"); + return -1; + } +#else + setuid(geteuid()); +#endif + + /* Sanity checks... */ + for (i = 0; i < strlen(new); i++) + if (!isalnum(new[i])) break; + if ((i != strlen(new)) || (strlen(new) < 1) || + (strlen(new) > 32)) { + fprintf(stderr, "Bad scheme name.\n"); + return -1; + } + if (strcmp(old, new) == 0) { + fprintf(stderr, "Scheme unchanged.\n"); + return 0; + } + + if (chdir(configpath) != 0) { + fprintf(stderr, "Could not change to %s.\n", configpath); + return -1; + } + + /* Shut down devices in old scheme */ + if ((fetch_stab() == 0) && (stop_scheme(new) != 0)) + return -1; + + /* Update scheme state */ + if (old[0]) + printf("Changing scheme from '%s' to '%s'...\n", old, new); + else + printf("Changing scheme to '%s'...\n", new); + + umask(022); + f = fopen(scheme, "w"); + if (f) { + fprintf(f, "%s\n", new); + fclose(f); + } else + perror("Could not set scheme."); + + /* Start up devices in new scheme */ + if (start_scheme() != 0) + fprintf(stderr, "Some devices did not start cleanly.\n"); + + } else { + if (old[0]) + printf("Current scheme: '%s'.\n", old); + else + printf("Current scheme: 'default'.\n"); + } + return 0; +} + +/*====================================================================*/ + +static void usage(char *name) +{ + int i; + fprintf(stderr, "usage: %s command [socket #]\n", name); + fprintf(stderr, " or %s [-c configpath] [-f scheme]" + " [-s stab] scheme [name]\n", name); + fprintf(stderr, " commands:"); + for (i = 0; i < NCMD; i++) + fprintf(stderr, " %s", cmdname[i]); + fprintf(stderr, "\n"); + exit(EXIT_FAILURE); +} + +/*====================================================================*/ + +#define MAX_SOCKS 8 + +int main(int argc, char *argv[]) +{ + int cmd, fd[MAX_SOCKS], ns, ret, i; + int optch, errflg = 0; + char *s, *opts = (getuid() == 0) ? "Vc:f:s:" : "V"; + + if (access("/var/lib/pcmcia", R_OK) == 0) { + scheme = "/var/lib/pcmcia/scheme"; + stabfile = "/var/lib/pcmcia/stab"; + } else { + scheme = "/var/run/pcmcia-scheme"; + stabfile = "/var/run/stab"; + } + + while ((optch = getopt(argc, argv, opts)) != -1) { + switch (optch) { + case 'V': + fprintf(stderr, "cardctl version " CS_PKG_RELEASE "\n"); + return 0; + break; + case 'c': + configpath = strdup(optarg); break; + case 'f': + scheme = strdup(optarg); break; + case 's': + stabfile = strdup(optarg); break; + default: + errflg = 1; break; + } + } + + if (errflg || (argc == optind) || (argc > optind+2)) + usage(argv[0]); + + if (geteuid() != 0) { + fprintf(stderr, "cardctl must be setuid root\n"); + exit(EXIT_FAILURE); + } + +#ifndef __BEOS__ + major = lookup_dev("pcmcia"); + if (major < 0) { + if (major == -ENODEV) + fprintf(stderr, "no pcmcia driver in /proc/devices\n"); + else + perror("could not open /proc/devices"); + exit(EXIT_FAILURE); + } +#endif + + if (strcmp(argv[optind], "scheme") == 0) { +#ifndef UNSAFE_TOOLS + setuid(getuid()); +#endif + if (do_scheme((argc == optind+1) ? NULL : argv[optind+1]) == 0) + exit(EXIT_SUCCESS); + else + exit(EXIT_FAILURE); + } + + for (cmd = 0; cmd < NCMD; cmd++) + if (strcmp(argv[optind], cmdname[cmd]) == 0) break; + if (cmd == NCMD) + usage(argv[0]); + + ret = 0; + if (argc == optind+2) { + ns = strtol(argv[optind+1], &s, 0); + if ((*argv[optind+1] == '\0') || (*s != '\0')) + usage(argv[0]); + fd[0] = open_sock(ns); + if (fd[0] < 0) { + perror("open_sock()"); + exit(EXIT_FAILURE); + } +#ifndef UNSAFE_TOOLS + setuid(getuid()); +#endif + ret = do_cmd(fd[0], cmd); + if (ret != 0) + perror("ioctl()"); + } else { + for (ns = 0; ns < MAX_SOCKS; ns++) { + fd[ns] = open_sock(ns); + if (fd[ns] < 0) break; + } +#ifndef UNSAFE_TOOLS + setuid(getuid()); +#endif + if (ns == 0) { + perror("open_sock()"); + exit(EXIT_FAILURE); + } + for (ns = 0; (ns < MAX_SOCKS) && (fd[ns] >= 0); ns++) { + if (cmd <= C_IDENT) + printf("Socket %d:\n", ns); + i = do_cmd(fd[ns], cmd); + if ((i != 0) && (errno != ENODEV)) { + perror("ioctl()"); + ret = i; + } + } + } + if (ret != 0) + exit(EXIT_FAILURE); + return 0; +} diff --git a/src/bin/pcmcia-cs/dump_cis.8 b/src/bin/pcmcia-cs/dump_cis.8 new file mode 100644 index 0000000000..be0c51b1f8 --- /dev/null +++ b/src/bin/pcmcia-cs/dump_cis.8 @@ -0,0 +1,48 @@ +.\" Copyright (C) 1998 David A. Hinds -- dahinds@users.sourceforge.net +.\" dump_cis.8 1.5 2000/06/12 21:24:48 +.\" +.TH DUMP_CIS 8 "2000/06/12 21:24:48" "pcmcia-cs" +.SH NAME +dump_cis \- display PCMCIA Card Information Structures +.SH SYNOPSIS +.B dump_cis +.RB [ -f ] +.RB [ -v ] +.RB [ "\-i\ "\c +.I infile\c +] +.SH DESCRIPTION +.B Dump_cis +retrieves and parses the Card Information Structures for inserted +PCMCIA devices, or optionally, parses CIS information from a file. +.PP +The +.B pack_cis +utility can parse a subset of the non-verbose output +of +.BR dump_cis , +so it is fairly easy to use +.B dump_cis +output as templates for +.BR pack_cis . +If a replacement CIS has been loaded for a card, +.B dump_cis +will display the replacement rather than the actual data on the card. +.SH OPTIONS +.TP +.B \-f +Force: attempt to decode any available CIS information even if the +overall CIS organization appears to be invalid. +.TP +.B \-v +Verbose output: display raw hex data for each tuple, and provide a +more complete dump of some tuple types. +.TP +.BI "\-i " infile +Read packed CIS data from a file (as created by +.BR pack_cis ) +instead of reading from active cards. +.SH AUTHOR +David Hinds \- dahinds@users.sourceforge.net +.SH "SEE ALSO" +pack_cis(8). diff --git a/src/bin/pcmcia-cs/dump_cis.c b/src/bin/pcmcia-cs/dump_cis.c new file mode 100644 index 0000000000..3c80c43d37 --- /dev/null +++ b/src/bin/pcmcia-cs/dump_cis.c @@ -0,0 +1,1112 @@ +/*====================================================================== + + PC Card CIS dump utility + + dump_cis.c 1.63 2001/11/30 23:10:17 + + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + + Alternatively, the contents of this file may be used under the + terms of the GNU General Public License version 2 (the "GPL"), in + which case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + +======================================================================*/ +#ifdef __BEOS__ +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static int verbose = 0; +static char indent[10] = " "; + +/*====================================================================*/ +#ifndef __BEOS__ +static int major = 0; + +static int lookup_dev(char *name) +{ + FILE *f; + int n; + char s[32], t[32]; + + f = fopen("/proc/devices", "r"); + if (f == NULL) + return -1; + while (fgets(s, 32, f) != NULL) { + if (sscanf(s, "%d %s", &n, t) == 2) + if (strcmp(name, t) == 0) + break; + } + fclose(f); + if (strcmp(name, t) == 0) + return n; + else + return -1; +} +#endif +/*====================================================================*/ + +static int open_sock(int sock) +{ +#ifdef __BEOS__ + char fn[B_OS_NAME_LENGTH]; + sprintf(fn, "/dev/bus/pcmcia/sock/%d", sock); + return open(fn, O_RDONLY); +#else + static char *paths[] = { + "/var/lib/pcmcia", "/var/run", "/dev", "/tmp", NULL + }; + int fd; + char **p, fn[64]; + dev_t dev = (major<<8) + sock; + + for (p = paths; *p; p++) { + sprintf(fn, "%s/dc%d", *p, getpid()); + if (mknod(fn, (S_IFCHR|S_IREAD|S_IWRITE), dev) == 0) { + fd = open(fn, O_RDONLY); + unlink(fn); + if (fd >= 0) + return fd; + if (errno == ENODEV) break; + } + } + return -1; +#endif +} /* open_sock */ + +/*====================================================================*/ + +static void print_tuple(tuple_parse_t *tup) +{ + int i; + printf("%soffset 0x%2.2x, tuple 0x%2.2x, link 0x%2.2x\n", + indent, tup->tuple.CISOffset, tup->tuple.TupleCode, + tup->tuple.TupleLink); + for (i = 0; i < tup->tuple.TupleDataLen; i++) { + if ((i % 16) == 0) printf("%s ", indent); + printf("%2.2x ", (u_char)tup->data[i]); + if ((i % 16) == 15) putchar('\n'); + } + if ((i % 16) != 0) putchar('\n'); +} + +/*====================================================================*/ + +static void print_funcid(cistpl_funcid_t *fn) +{ + printf("%sfuncid ", indent); + switch (fn->func) { + case CISTPL_FUNCID_MULTI: + printf("multi_function"); break; + case CISTPL_FUNCID_MEMORY: + printf("memory_card"); break; + case CISTPL_FUNCID_SERIAL: + printf("serial_port"); break; + case CISTPL_FUNCID_PARALLEL: + printf("parallel_port"); break; + case CISTPL_FUNCID_FIXED: + printf("fixed_disk"); break; + case CISTPL_FUNCID_VIDEO: + printf("video_adapter"); break; + case CISTPL_FUNCID_NETWORK: + printf("network_adapter"); break; + case CISTPL_FUNCID_AIMS: + printf("aims_card"); break; + case CISTPL_FUNCID_SCSI: + printf("scsi_adapter"); break; + default: + printf("unknown"); break; + } + if (fn->sysinit & CISTPL_SYSINIT_POST) + printf(" [post]"); + if (fn->sysinit & CISTPL_SYSINIT_ROM) + printf(" [rom]"); + putchar('\n'); +} + +/*====================================================================*/ + +static void print_size(u_int size) +{ + if (size < 1024) + printf("%ub", size); + else if (size < 1024*1024) + printf("%ukb", size/1024); + else + printf("%umb", size/(1024*1024)); +} + +static void print_unit(u_int v, char *unit, char tag) +{ + int n; + for (n = 0; (v % 1000) == 0; n++) v /= 1000; + printf("%u", v); + if (n < strlen(unit)) putchar(unit[n]); + putchar(tag); +} + +static void print_time(u_int tm, u_long scale) +{ + print_unit(tm * scale, "num", 's'); +} + +static void print_volt(u_int vi) +{ + print_unit(vi * 10, "um", 'V'); +} + +static void print_current(u_int ii) +{ + print_unit(ii / 10, "um", 'A'); +} + +static void print_speed(u_int b) +{ + if (b < 1000) + printf("%u bits/sec", b); + else if (b < 1000000) + printf("%u kb/sec", b/1000); + else + printf("%u mb/sec", b/1000000); +} + +/*====================================================================*/ + +static const char *dtype[] = { + "NULL", "ROM", "OTPROM", "EPROM", "EEPROM", "FLASH", "SRAM", + "DRAM", "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", "fn_specific", + "extended", "rsvd" +}; + +static void print_device(cistpl_device_t *dev) +{ + int i; + for (i = 0; i < dev->ndev; i++) { + printf("%s %s ", indent, dtype[dev->dev[i].type]); + printf("%uns, ", dev->dev[i].speed); + print_size(dev->dev[i].size); + putchar('\n'); + } + if (dev->ndev == 0) + printf("%s no_info\n", indent); +} + +/*====================================================================*/ + +static void print_power(char *tag, cistpl_power_t *power) +{ + int i, n; + for (i = n = 0; i < 8; i++) + if (power->present & (1<present & (1<param[CISTPL_POWER_VNOM]); + } + if (power->present & (1<param[CISTPL_POWER_VMIN]); + } + if (power->present & (1<param[CISTPL_POWER_VMAX]); + } + if (power->present & (1<param[CISTPL_POWER_ISTATIC]); + } + if (power->present & (1<param[CISTPL_POWER_IAVG]); + } + if (power->present & (1<param[CISTPL_POWER_IPEAK]); + } + if (power->present & (1<param[CISTPL_POWER_IDOWN]); + } + if (power->flags & CISTPL_POWER_HIGHZ_OK) { + if (++i == 5) printf("\n%s ", indent); + printf(" [highz OK]"); + } + if (power->flags & CISTPL_POWER_HIGHZ_REQ) { + printf(" [highz]"); + } + putchar('\n'); +} + +/*====================================================================*/ + +static void print_cftable_entry(cistpl_cftable_entry_t *entry) +{ + int i; + + printf("%scftable_entry 0x%2.2x%s\n", indent, entry->index, + (entry->flags & CISTPL_CFTABLE_DEFAULT) ? " [default]" : ""); + + if (entry->flags & ~CISTPL_CFTABLE_DEFAULT) { + printf("%s ", indent); + if (entry->flags & CISTPL_CFTABLE_BVDS) + printf(" [bvd]"); + if (entry->flags & CISTPL_CFTABLE_WP) + printf(" [wp]"); + if (entry->flags & CISTPL_CFTABLE_RDYBSY) + printf(" [rdybsy]"); + if (entry->flags & CISTPL_CFTABLE_MWAIT) + printf(" [mwait]"); + if (entry->flags & CISTPL_CFTABLE_AUDIO) + printf(" [audio]"); + if (entry->flags & CISTPL_CFTABLE_READONLY) + printf(" [readonly]"); + if (entry->flags & CISTPL_CFTABLE_PWRDOWN) + printf(" [pwrdown]"); + putchar('\n'); + } + + if (entry->vcc.present) + print_power("Vcc", &entry->vcc); + if (entry->vpp1.present) + print_power("Vpp1", &entry->vpp1); + if (entry->vpp2.present) + print_power("Vpp2", &entry->vpp2); + + if ((entry->timing.wait != 0) || (entry->timing.ready != 0) || + (entry->timing.reserved != 0)) { + printf("%s timing", indent); + if (entry->timing.wait != 0) { + printf(" wait "); + print_time(entry->timing.wait, entry->timing.waitscale); + } + if (entry->timing.ready != 0) { + printf(" ready "); + print_time(entry->timing.ready, entry->timing.rdyscale); + } + if (entry->timing.reserved != 0) { + printf(" reserved "); + print_time(entry->timing.reserved, entry->timing.rsvscale); + } + putchar('\n'); + } + + if (entry->io.nwin) { + cistpl_io_t *io = &entry->io; + printf("%s io", indent); + for (i = 0; i < io->nwin; i++) { + if (i) putchar(','); + printf(" 0x%4.4x-0x%4.4x", io->win[i].base, + io->win[i].base+io->win[i].len-1); + } + printf(" [lines=%d]", io->flags & CISTPL_IO_LINES_MASK); + if (io->flags & CISTPL_IO_8BIT) printf(" [8bit]"); + if (io->flags & CISTPL_IO_16BIT) printf(" [16bit]"); + if (io->flags & CISTPL_IO_RANGE) printf(" [range]"); + putchar('\n'); + } + + if (entry->irq.IRQInfo1) { + printf("%s irq ", indent); + if (entry->irq.IRQInfo1 & IRQ_INFO2_VALID) + printf("mask 0x%04x", entry->irq.IRQInfo2); + else + printf("%u", entry->irq.IRQInfo1 & IRQ_MASK); + if (entry->irq.IRQInfo1 & IRQ_LEVEL_ID) printf(" [level]"); + if (entry->irq.IRQInfo1 & IRQ_PULSE_ID) printf(" [pulse]"); + if (entry->irq.IRQInfo1 & IRQ_SHARE_ID) printf(" [shared]"); + putchar('\n'); + } + + if (entry->mem.nwin) { + cistpl_mem_t *mem = &entry->mem; + printf("%s memory", indent); + for (i = 0; i < mem->nwin; i++) { + if (i) putchar(','); + printf(" 0x%4.4x-0x%4.4x @ 0x%4.4x", mem->win[i].card_addr, + mem->win[i].card_addr + mem->win[i].len-1, + mem->win[i].host_addr); + } + putchar('\n'); + } + + if (verbose && entry->subtuples) + printf("%s %d bytes in subtuples\n", indent, entry->subtuples); + +} + +/*====================================================================*/ + +static void print_cftable_entry_cb(cistpl_cftable_entry_cb_t *entry) +{ + int i; + + printf("%scftable_entry_cb 0x%2.2x%s\n", indent, entry->index, + (entry->flags & CISTPL_CFTABLE_DEFAULT) ? " [default]" : ""); + + if (entry->flags & ~CISTPL_CFTABLE_DEFAULT) { + printf("%s ", indent); + if (entry->flags & CISTPL_CFTABLE_MASTER) + printf(" [master]"); + if (entry->flags & CISTPL_CFTABLE_INVALIDATE) + printf(" [invalidate]"); + if (entry->flags & CISTPL_CFTABLE_VGA_PALETTE) + printf(" [vga palette]"); + if (entry->flags & CISTPL_CFTABLE_PARITY) + printf(" [parity]"); + if (entry->flags & CISTPL_CFTABLE_WAIT) + printf(" [wait]"); + if (entry->flags & CISTPL_CFTABLE_SERR) + printf(" [serr]"); + if (entry->flags & CISTPL_CFTABLE_FAST_BACK) + printf(" [fast back]"); + if (entry->flags & CISTPL_CFTABLE_BINARY_AUDIO) + printf(" [binary audio]"); + if (entry->flags & CISTPL_CFTABLE_PWM_AUDIO) + printf(" [pwm audio]"); + putchar('\n'); + } + + if (entry->vcc.present) + print_power("Vcc", &entry->vcc); + if (entry->vpp1.present) + print_power("Vpp1", &entry->vpp1); + if (entry->vpp2.present) + print_power("Vpp2", &entry->vpp2); + + if (entry->io) { + printf("%s io_base", indent); + for (i = 0; i < 8; i++) + if (entry->io & (1<irq.IRQInfo1) { + printf("%s irq ", indent); + if (entry->irq.IRQInfo1 & IRQ_INFO2_VALID) + printf("mask 0x%4.4x", entry->irq.IRQInfo2); + else + printf("%u", entry->irq.IRQInfo1 & IRQ_MASK); + if (entry->irq.IRQInfo1 & IRQ_LEVEL_ID) printf(" [level]"); + if (entry->irq.IRQInfo1 & IRQ_PULSE_ID) printf(" [pulse]"); + if (entry->irq.IRQInfo1 & IRQ_SHARE_ID) printf(" [shared]"); + putchar('\n'); + } + + if (entry->mem) { + printf("%s mem_base", indent); + for (i = 0; i < 8; i++) + if (entry->mem & (1<subtuples) + printf("%s %d bytes in subtuples\n", indent, entry->subtuples); + +} + +/*====================================================================*/ + +static void print_jedec(cistpl_jedec_t *j) +{ + int i; + for (i = 0; i < j->nid; i++) { + if (i != 0) putchar(','); + printf(" 0x%02x 0x%02x", j->id[i].mfr, j->id[i].info); + } + putchar('\n'); +} + +/*====================================================================*/ + +static void print_device_geo(cistpl_device_geo_t *geo) +{ + int i; + for (i = 0; i < geo->ngeo; i++) { + printf("%s width %d erase 0x%x read 0x%x write 0x%x " + "partition 0x%x interleave 0x%x\n", indent, + geo->geo[i].buswidth, geo->geo[i].erase_block, + geo->geo[i].read_block, geo->geo[i].write_block, + geo->geo[i].partition, geo->geo[i].interleave); + } +} + +/*====================================================================*/ + +static void print_org(cistpl_org_t *org) +{ + printf("%sdata_org ", indent); + switch (org->data_org) { + case CISTPL_ORG_FS: + printf("[filesystem]"); break; + case CISTPL_ORG_APPSPEC: + printf("[app_specific]"); break; + case CISTPL_ORG_XIP: + printf("[code]"); break; + default: + if (org->data_org < 0x80) + printf("[reserved]"); + else + printf("[vendor_specific]"); + } + printf(", \"%s\"\n", org->desc); +} + +/*====================================================================*/ + +static char *data_mod[] = { + "Bell103", "V.21", "V.23", "V.22", "Bell212A", "V.22bis", + "V.26", "V.26bis", "V.27bis", "V.29", "V.32", "V.32bis", + "V.34", "rfu", "rfu", "rfu" +}; +static char *fax_mod[] = { + "V.21-C2", "V.27ter", "V.29", "V.17", "V.33", "rfu", "rfu", "rfu" +}; +static char *fax_features[] = { + "T.3", "T.4", "T.6", "error", "voice", "poll", "file", "passwd" +}; +static char *cmd_protocol[] = { + "AT1", "AT2", "AT3", "MNP_AT", "V.25bis", "V.25A", "DMCL" +}; +static char *uart[] = { + "8250", "16450", "16550", "8251", "8530", "85230" +}; +static char *parity[] = { "space", "mark", "odd", "even" }; +static char *stop[] = { "1", "1.5", "2" }; +static char *flow[] = { + "XON/XOFF xmit", "XON/XOFF rcv", "hw xmit", "hw rcv", "transparent" +}; +static void print_serial(cistpl_funce_t *funce) +{ + cistpl_serial_t *s; + cistpl_data_serv_t *ds; + cistpl_fax_serv_t *fs; + cistpl_modem_cap_t *cp; + int i, j; + + switch (funce->type & 0x0f) { + case CISTPL_FUNCE_SERIAL_IF: + case CISTPL_FUNCE_SERIAL_IF_DATA: + case CISTPL_FUNCE_SERIAL_IF_FAX: + case CISTPL_FUNCE_SERIAL_IF_VOICE: + s = (cistpl_serial_t *)(funce->data); + printf("%sserial_interface", indent); + if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_IF_DATA) + printf("_data"); + else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_IF_FAX) + printf("_fax"); + else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_IF_VOICE) + printf("_voice"); + printf("\n%s uart %s", indent, + (s->uart_type < 6) ? uart[s->uart_type] : "reserved"); + if (s->uart_cap_0) { + printf(" ["); + for (i = 0; i < 4; i++) + if (s->uart_cap_0 & (1<uart_cap_0 >= (2<uart_cap_1) { + int m = s->uart_cap_1 & 0x0f; + int n = s->uart_cap_1 >> 4; + printf(" ["); + for (i = 0; i < 4; i++) + if (m & (1<= (2<= (2<data); + printf("%sserial_modem_cap", indent); + if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_CAP_DATA) + printf("_data"); + else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_CAP_FAX) + printf("_fax"); + else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_CAP_VOICE) + printf("_voice"); + if (cp->flow) { + printf("\n%s flow", indent); + for (i = 0; i < 5; i++) + if (cp->flow & (1<cmd_buf+1), + cp->rcv_buf_0+(cp->rcv_buf_1<<8)+(cp->rcv_buf_2<<16), + cp->xmit_buf_0+(cp->xmit_buf_1<<8)+(cp->xmit_buf_2<<16)); + break; + case CISTPL_FUNCE_SERIAL_SERV_DATA: + ds = (cistpl_data_serv_t *)(funce->data); + printf("%sserial_data_services\n", indent); + printf("%s data_rate %d\n", indent, + 75*((ds->max_data_0<<8) + ds->max_data_1)); + printf("%s modulation", indent); + for (i = j = 0; i < 16; i++) + if (((ds->modulation_1<<8) + ds->modulation_0) & (1<error_control) { + printf("%s error_control", indent); + if (ds->error_control & CISTPL_SERIAL_ERR_MNP2_4) + printf(" [MNP2-4]"); + if (ds->error_control & CISTPL_SERIAL_ERR_V42_LAPM) + printf(" [V.42/LAPM]"); + printf("\n"); + } + if (ds->compression) { + printf("%s compression", indent); + if (ds->compression & CISTPL_SERIAL_CMPR_V42BIS) + printf(" [V.42bis]"); + if (ds->compression & CISTPL_SERIAL_CMPR_MNP5) + printf(" [MNP5]"); + printf("\n"); + } + if (ds->cmd_protocol) { + printf("%s cmd_protocol", indent); + for (i = 0; i < 7; i++) + if (ds->cmd_protocol & (1<data); + printf("%sserial_fax_services [class=%d]\n", + indent, funce->type>>4); + printf("%s data_rate %d\n", indent, + 75*((fs->max_data_0<<8) + fs->max_data_1)); + printf("%s modulation", indent); + for (i = 0; i < 8; i++) + if (fs->modulation & (1<features_0) { + printf("%s features", indent); + for (i = 0; i < 8; i++) + if (fs->features_0 & (1<type) { + case CISTPL_FUNCE_IDE_IFACE: + i = (cistpl_ide_interface_t *)(funce->data); + printf("%sdisk_interface ", indent); + if (i->interface == CISTPL_IDE_INTERFACE) + printf("[ide]\n"); + else + printf("[undefined]\n"); + break; + case CISTPL_FUNCE_IDE_MASTER: + case CISTPL_FUNCE_IDE_SLAVE: + f = (cistpl_ide_feature_t *)(funce->data); + printf("%sdisk_features", indent); + if (f->feature1 & CISTPL_IDE_SILICON) + printf(" [silicon]"); + else + printf(" [rotating]"); + if (f->feature1 & CISTPL_IDE_UNIQUE) + printf(" [unique]"); + if (f->feature1 & CISTPL_IDE_DUAL) + printf(" [dual]"); + else + printf(" [single]"); + if (f->feature1 && f->feature2) + printf("\n%s ", indent); + if (f->feature2 & CISTPL_IDE_HAS_SLEEP) + printf(" [sleep]"); + if (f->feature2 & CISTPL_IDE_HAS_STANDBY) + printf(" [standby]"); + if (f->feature2 & CISTPL_IDE_HAS_IDLE) + printf(" [idle]"); + if (f->feature2 & CISTPL_IDE_LOW_POWER) + printf(" [low power]"); + if (f->feature2 & CISTPL_IDE_REG_INHIBIT) + printf(" [reg inhibit]"); + if (f->feature2 & CISTPL_IDE_HAS_INDEX) + printf(" [index]"); + if (f->feature2 & CISTPL_IDE_IOIS16) + printf(" [iois16]"); + putchar('\n'); + break; + } +} + +/*====================================================================*/ + +static const char *tech[] = { + "undefined", "ARCnet", "ethernet", "token_ring", "localtalk", + "FDDI/CDDI", "ATM", "wireless" +}; + +static const char *media[] = { + "undefined", "unshielded_twisted_pair", "shielded_twisted_pair", + "thin_coax", "thick_coax", "fiber", "900_MHz", "2.4_GHz", + "5.4_GHz", "diffuse_infrared", "point_to_point_infrared" +}; + +static void print_network(cistpl_funce_t *funce) +{ + cistpl_lan_tech_t *t; + cistpl_lan_speed_t *s; + cistpl_lan_media_t *m; + cistpl_lan_node_id_t *n; + cistpl_lan_connector_t *c; + int i; + + switch (funce->type) { + case CISTPL_FUNCE_LAN_TECH: + t = (cistpl_lan_tech_t *)(funce->data); + printf("%slan_technology %s\n", indent, tech[t->tech]); + break; + case CISTPL_FUNCE_LAN_SPEED: + s = (cistpl_lan_speed_t *)(funce->data); + printf("%slan_speed ", indent); + print_speed(s->speed); + putchar('\n'); + break; + case CISTPL_FUNCE_LAN_MEDIA: + m = (cistpl_lan_media_t *)(funce->data); + printf("%slan_media %s\n", indent, media[m->media]); + break; + case CISTPL_FUNCE_LAN_NODE_ID: + n = (cistpl_lan_node_id_t *)(funce->data); + printf("%slan_node_id", indent); + for (i = 0; i < n->nb; i++) + printf(" %02x", n->id[i]); + putchar('\n'); + break; + case CISTPL_FUNCE_LAN_CONNECTOR: + c = (cistpl_lan_connector_t *)(funce->data); + printf("%slan_connector ", indent); + if (c->code == 0) + printf("Open connector standard\n"); + else + printf("Closed connector standard\n"); + break; + } +} + +/*====================================================================*/ + +static void print_vers_1(cistpl_vers_1_t *v1) +{ + int i, n; + char s[32]; + sprintf(s, "%svers_1 %d.%d", indent, v1->major, v1->minor); + printf("%s", s); + n = strlen(s); + for (i = 0; i < v1->ns; i++) { + if (n + strlen(v1->str + v1->ofs[i]) + 4 > 72) { + n = strlen(indent) + 2; + printf(",\n%s ", indent); + } else { + printf(", "); + n += 2; + } + printf("\"%s\"", v1->str + v1->ofs[i]); + n += strlen(v1->str + v1->ofs[i]) + 2; + } + putchar('\n'); +} + +/*====================================================================*/ + +static void print_vers_2(cistpl_vers_2_t *v2) +{ + printf("%sversion 0x%2.2x, compliance 0x%2.2x, dindex 0x%4.4x\n", + indent, v2->vers, v2->comply, v2->dindex); + printf("%s vspec8 0x%2.2x, vspec9 0x%2.2x, nhdr %d\n", + indent, v2->vspec8, v2->vspec9, v2->nhdr); + printf("%s vendor \"%s\"\n", indent, v2->str+v2->vendor); + printf("%s info \"%s\"\n", indent, v2->str+v2->info); +} + +/*====================================================================*/ + +#ifdef CISTPL_FORMAT_DISK +static void print_format(cistpl_format_t *fmt) +{ + if (fmt->type == CISTPL_FORMAT_DISK) + printf("%s [disk]", indent); + else if (fmt->type == CISTPL_FORMAT_MEM) + printf("%s [memory]", indent); + else + printf("%s [type 0x%02x]\n", indent, fmt->type); + if (fmt->edc == CISTPL_EDC_NONE) + printf(" [no edc]"); + else if (fmt->edc == CISTPL_EDC_CKSUM) + printf(" [cksum]"); + else if (fmt->edc == CISTPL_EDC_CRC) + printf(" [crc]"); + else if (fmt->edc == CISTPL_EDC_PCC) + printf(" [pcc]"); + else + printf(" [edc 0x%02x]", fmt->edc); + printf(" offset 0x%04x length ", fmt->offset); + print_size(fmt->length); + putchar('\n'); +} +#endif + +/*====================================================================*/ + +static void print_config(int code, cistpl_config_t *cfg) +{ + printf("%sconfig%s base 0x%4.4x", indent, + (code == CISTPL_CONFIG_CB) ? "_cb" : "", + cfg->base); + if (code == CISTPL_CONFIG) + printf(" mask 0x%4.4x", cfg->rmask[0]); + printf(" last_index 0x%2.2x\n", cfg->last_idx); + if (verbose && cfg->subtuples) + printf("%s %d bytes in subtuples\n", indent, cfg->subtuples); +} + +/*====================================================================*/ + +static int nfn = 0, cur = 0; + +static void print_parse(tuple_parse_t *tup) +{ + static int func = 0; + int i; + + switch (tup->tuple.TupleCode) { + case CISTPL_DEVICE: + case CISTPL_DEVICE_A: + if (tup->tuple.TupleCode == CISTPL_DEVICE) + printf("%sdev_info\n", indent); + else + printf("%sattr_dev_info\n", indent); + print_device(&tup->parse.device); + break; + case CISTPL_CHECKSUM: + printf("%schecksum 0x%04x-0x%04x = 0x%02x\n", + indent, tup->parse.checksum.addr, + tup->parse.checksum.addr+tup->parse.checksum.len-1, + tup->parse.checksum.sum); + break; + case CISTPL_LONGLINK_A: + if (verbose) + printf("%slong_link_attr 0x%04x\n", indent, + tup->parse.longlink.addr); + break; + case CISTPL_LONGLINK_C: + if (verbose) + printf("%slong_link 0x%04x\n", indent, + tup->parse.longlink.addr); + break; + case CISTPL_LONGLINK_MFC: + if (verbose) { + printf("%smfc_long_link\n", indent); + for (i = 0; i < tup->parse.longlink_mfc.nfn; i++) + printf("%s function %d: %s 0x%04x\n", indent, i, + tup->parse.longlink_mfc.fn[i].space ? "common" : "attr", + tup->parse.longlink_mfc.fn[i].addr); + } else { + printf("%smfc {\n", indent); + nfn = tup->parse.longlink_mfc.nfn; + cur = 0; + strcat(indent, " "); + } + break; + case CISTPL_NO_LINK: + if (verbose) + printf("%sno_long_link\n", indent); + break; +#ifdef CISTPL_INDIRECT + case CISTPL_INDIRECT: + if (verbose) + printf("%sindirect_access\n", indent); + break; +#endif + case CISTPL_LINKTARGET: + if (verbose) + printf("%slink_target\n", indent); + else { + if (cur++) printf("%s}, {\n", indent+2); + } + break; + case CISTPL_VERS_1: + print_vers_1(&tup->parse.version_1); + break; + case CISTPL_ALTSTR: + break; + case CISTPL_JEDEC_A: + case CISTPL_JEDEC_C: + if (tup->tuple.TupleCode == CISTPL_JEDEC_C) + printf("%scommon_jedec", indent); + else + printf("%sattr_jedec", indent); + print_jedec(&tup->parse.jedec); + break; + case CISTPL_DEVICE_GEO: + case CISTPL_DEVICE_GEO_A: + if (tup->tuple.TupleCode == CISTPL_DEVICE_GEO) + printf("%scommon_geometry\n", indent); + else + printf("%sattr_geometry\n", indent); + print_device_geo(&tup->parse.device_geo); + break; + case CISTPL_MANFID: + printf("%smanfid 0x%4.4x, 0x%4.4x\n", indent, + tup->parse.manfid.manf, tup->parse.manfid.card); + break; + case CISTPL_FUNCID: + print_funcid(&tup->parse.funcid); + func = tup->parse.funcid.func; + break; + case CISTPL_FUNCE: + switch (func) { + case CISTPL_FUNCID_SERIAL: + print_serial(&tup->parse.funce); + break; + case CISTPL_FUNCID_FIXED: + print_fixed(&tup->parse.funce); + break; + case CISTPL_FUNCID_NETWORK: + print_network(&tup->parse.funce); + break; + } + break; + case CISTPL_BAR: + printf("%sBAR %d size ", indent, + tup->parse.bar.attr & CISTPL_BAR_SPACE); + print_size(tup->parse.bar.size); + if (tup->parse.bar.attr & CISTPL_BAR_SPACE_IO) + printf(" [io]"); + else + printf(" [mem]"); + if (tup->parse.bar.attr & CISTPL_BAR_PREFETCH) + printf(" [prefetch]"); + if (tup->parse.bar.attr & CISTPL_BAR_CACHEABLE) + printf(" [cacheable]"); + if (tup->parse.bar.attr & CISTPL_BAR_1MEG_MAP) + printf(" [<1mb]"); + putchar('\n'); + break; + case CISTPL_CONFIG: + case CISTPL_CONFIG_CB: + print_config(tup->tuple.TupleCode, &tup->parse.config); + break; + case CISTPL_CFTABLE_ENTRY: + print_cftable_entry(&tup->parse.cftable_entry); + break; + case CISTPL_CFTABLE_ENTRY_CB: + print_cftable_entry_cb(&tup->parse.cftable_entry_cb); + break; + case CISTPL_VERS_2: + print_vers_2(&tup->parse.vers_2); + break; + case CISTPL_ORG: + print_org(&tup->parse.org); + break; +#ifdef CISTPL_FORMAT_DISK + case CISTPL_FORMAT: + case CISTPL_FORMAT_A: + if (tup->tuple.TupleCode == CISTPL_FORMAT) + printf("%scommon_format\n", indent); + else + printf("%sattr_format\n", indent); + print_format(&tup->parse.format); +#endif + } +} + +/*====================================================================*/ + +static int get_tuple_buf(int fd, ds_ioctl_arg_t *arg, int first) +{ + u_int ofs; + static int nb = 0; + static u_char buf[1024]; + + if (first) { + nb = read(fd, buf, sizeof(buf)); + arg->tuple.TupleLink = arg->tuple.CISOffset = 0; + } + ofs = arg->tuple.CISOffset + arg->tuple.TupleLink; + if (ofs >= nb) return -1; + arg->tuple.TupleCode = buf[ofs++]; + arg->tuple.TupleDataLen = arg->tuple.TupleLink = buf[ofs++]; + arg->tuple.CISOffset = ofs; + memcpy(arg->tuple_parse.data, buf+ofs, arg->tuple.TupleLink); + return 0; +} + +static int get_tuple(int fd, ds_ioctl_arg_t *arg, int first) +{ + int cmd = (first) ? DS_GET_FIRST_TUPLE : DS_GET_NEXT_TUPLE; + if (ioctl(fd, cmd, arg) != 0) { + if (errno == ENODEV) + printf("%sno card\n", indent); + else if (errno != ENODATA) + printf("%sget tuple: %s\n", indent, strerror(errno)); + return -1; + } + if (ioctl(fd, DS_GET_TUPLE_DATA, arg) != 0) { + printf("%sget tuple data: %s\n", indent, strerror(errno)); + return -1; + } + return 0; +} + +/*====================================================================*/ + +#define MAX_SOCKS 8 + +int main(int argc, char *argv[]) +{ + int i, fd, pfd = -1; + ds_ioctl_arg_t arg; + int optch, errflg, first; + int force = 0; + char *infile = NULL; + + errflg = 0; + while ((optch = getopt(argc, argv, "fvi:")) != -1) { + switch (optch) { + case 'f': + force = 1; break; + case 'v': + verbose = 1; break; + case 'i': + infile = strdup(optarg); break; + default: + errflg = 1; break; + } + } + if (errflg || (optind < argc)) { + fprintf(stderr, "usage: %s [-v] [-f] [-i infile]\n", argv[0]); + exit(EXIT_FAILURE); + } + +#ifndef __BEOS__ + major = lookup_dev("pcmcia"); + if (major < 0) { + fprintf(stderr, "no pcmcia driver in /proc/devices\n"); + exit(EXIT_FAILURE); + } +#endif + + for (i = 0; (i < MAX_SOCKS) && !(i && infile); i++) { + nfn = cur = 0; + if (infile) { + indent[0] = '\0'; + fd = open(infile, O_RDONLY); + if (fd < 0) { + perror("open()"); + return -1; + } + pfd = open_sock(0); + } else { + strcpy(indent, " "); + fd = pfd = open_sock(i); + } + if (pfd < 0) + break; + if (!verbose && (i > 0)) putchar('\n'); + if (!infile) printf("Socket %d:\n", i); + + if (!force && !infile) { + if (ioctl(fd, DS_VALIDATE_CIS, &arg) != 0) { + printf("%svalidate CIS: %s\n", indent, strerror(errno)); + continue; + } + if (arg.cisinfo.Chains == 0) { + printf("%sno CIS present\n", indent); + continue; + } + } + + arg.tuple.TupleDataMax = sizeof(arg.tuple_parse.data); + arg.tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON; + arg.tuple.DesiredTuple = RETURN_FIRST_TUPLE; + arg.tuple.TupleOffset = 0; + + for (first = 1; ; first = 0) { + if (infile) { + if (get_tuple_buf(fd, &arg, first) != 0) break; + } else { + if (get_tuple(fd, &arg, first) != 0) break; + } + if (verbose) print_tuple(&arg.tuple_parse); + if (ioctl(pfd, DS_PARSE_TUPLE, &arg) == 0) + print_parse(&arg.tuple_parse); + else if (errno != ENOSYS) + printf("%sparse error: %s\n", indent, + strerror(errno)); + if (verbose) putchar('\n'); + if (arg.tuple.TupleCode == CISTPL_END) + break; + } + + if (!verbose && (nfn > 0)) + printf("%s}\n", indent+2); + } + if ((i == 0) && (pfd < 0)) { + perror("open()"); + return -1; + } + + return 0; +} diff --git a/src/bin/pcmcia-cs/dump_cisreg.c b/src/bin/pcmcia-cs/dump_cisreg.c new file mode 100644 index 0000000000..66a6f9072e --- /dev/null +++ b/src/bin/pcmcia-cs/dump_cisreg.c @@ -0,0 +1,288 @@ +/*====================================================================== + + PCMCIA card configuration register dump + + dump_cisreg.c 1.31 2001/11/30 23:10:17 + + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + + Alternatively, the contents of this file may be used under the + terms of the GNU General Public License version 2 (the "GPL"), in + which case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + +======================================================================*/ +#ifdef __BEOS__ +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*====================================================================*/ +#ifndef __BEOS__ +static int major = 0; + +static int lookup_dev(char *name) +{ + FILE *f; + int n; + char s[32], t[32]; + + f = fopen("/proc/devices", "r"); + if (f == NULL) + return -1; + while (fgets(s, 32, f) != NULL) { + if (sscanf(s, "%d %s", &n, t) == 2) + if (strcmp(name, t) == 0) + break; + } + fclose(f); + if (strcmp(name, t) == 0) + return n; + else + return -1; +} +#endif + +/*====================================================================*/ + +static int open_sock(int sock) +{ +#ifdef __BEOS__ + char fn[B_OS_NAME_LENGTH]; + sprintf(fn, "/dev/bus/pcmcia/sock/%d", sock); + return open(fn, O_RDONLY); +#else + static char *paths[] = { + "/var/lib/pcmcia", "/var/run", "/dev", "/tmp", NULL + }; + int fd; + char **p, fn[64]; + dev_t dev = (major<<8) + sock; + + for (p = paths; *p; p++) { + sprintf(fn, "%s/dc%d", *p, getpid()); + if (mknod(fn, (S_IFCHR|S_IREAD|S_IWRITE), dev) == 0) { + fd = open(fn, O_RDONLY); + unlink(fn); + if (fd >= 0) + return fd; + if (errno == ENODEV) break; + } + } + return -1; +#endif +} /* open_sock */ + +/*====================================================================*/ + +static int get_reg(int fd, int fn, off_t off) +{ + ds_ioctl_arg_t arg; + int ret; + + arg.conf_reg.Function = fn; + arg.conf_reg.Action = CS_READ; + arg.conf_reg.Offset = off; + ret = ioctl(fd, DS_ACCESS_CONFIGURATION_REGISTER, &arg); + if (ret != 0) { + printf(" read config register: %s\n\n", strerror(errno)); + return -1; + } + return arg.conf_reg.Value; +} + +static int dump_option(int fd, int fn, int mfc) +{ + int v = get_reg(fd, fn, CISREG_COR); + + if (v == -1) return -1; + printf(" Configuration option register = %#2.2x\n", v); + printf(" "); + if (v & COR_LEVEL_REQ) printf(" [level_req]"); + if (v & COR_SOFT_RESET) printf(" [soft_reset]"); + if (mfc) { + if (v & COR_FUNC_ENA) printf(" [func_ena]"); + if (v & COR_ADDR_DECODE) printf(" [addr_decode]"); + if (v & COR_IREQ_ENA) printf(" [ireq_ena]"); + printf(" [index = %#2.2x]\n", v & COR_MFC_CONFIG_MASK); + } else + printf(" [index = %#2.2x]\n", v & COR_CONFIG_MASK); + return 0; +} + +static void dump_status(int fd, int fn) +{ + int v = get_reg(fd, fn, CISREG_CCSR); + + printf(" Card configuration and status register = %#2.2x\n", v); + printf(" "); + if (v & CCSR_INTR_ACK) printf(" [intr_ack]"); + if (v & CCSR_INTR_PENDING) printf(" [intr_pending]"); + if (v & CCSR_POWER_DOWN) printf(" [power_down]"); + if (v & CCSR_AUDIO_ENA) printf(" [audio]"); + if (v & CCSR_IOIS8) printf(" [IOis8]"); + if (v & CCSR_SIGCHG_ENA) printf(" [sigchg]"); + if (v & CCSR_CHANGED) printf(" [changed]"); + printf("\n"); +} + +static void dump_pin(int fd, int fn) +{ + int v = get_reg(fd, fn, CISREG_PRR); + + printf(" Pin replacement register = %#2.2x\n", v); + printf(" "); + if (v & PRR_WP_STATUS) printf(" [wp]"); + if (v & PRR_READY_STATUS) printf(" [ready]"); + if (v & PRR_BVD2_STATUS) printf(" [bvd2]"); + if (v & PRR_BVD1_STATUS) printf(" [bvd1]"); + if (v & PRR_WP_EVENT) printf(" [wp_event]"); + if (v & PRR_READY_EVENT) printf(" [ready_event]"); + if (v & PRR_BVD2_EVENT) printf(" [bvd2_event]"); + if (v & PRR_BVD1_EVENT) printf(" [bvd1_event]"); + printf("\n"); +} + +static void dump_copy(int fd, int fn) +{ + int v = get_reg(fd, fn, CISREG_SCR); + + printf(" Socket and copy register = %#2.2x\n", v); + printf(" [socket = %d] [copy = %d]\n", + v & SCR_SOCKET_NUM, + (v & SCR_COPY_NUM) >> 4); +} + +static void dump_ext_status(int fd, int fn) +{ + int v = get_reg(fd, fn, CISREG_ESR); + printf(" Extended status register = %#2.2x\n", v); + printf(" "); + if (v & ESR_REQ_ATTN_ENA) printf(" [req_attn_ena]"); + if (v & ESR_REQ_ATTN) printf(" [req_attn]"); + printf("\n"); +} + +/*====================================================================*/ + +static void dump_all(int fd, int fn, int mfc, u_int mask) +{ + int addr; + if (mask & PRESENT_OPTION) { + if (dump_option(fd, fn, mfc) != 0) + return; + } + if (mask & PRESENT_STATUS) + dump_status(fd, fn); + if (mask & PRESENT_PIN_REPLACE) + dump_pin(fd, fn); + if (mask & PRESENT_COPY) + dump_copy(fd, fn); + if (mask & PRESENT_EXT_STATUS) + dump_ext_status(fd, fn); + if (mask & PRESENT_IOBASE_0) { + addr = get_reg(fd, fn, CISREG_IOBASE_0); + addr += get_reg(fd, fn, CISREG_IOBASE_1) << 8; + printf(" IO base = 0x%04x\n", addr); + } + if (mask & PRESENT_IOSIZE) + printf(" IO size = %d\n", get_reg(fd, fn, CISREG_IOSIZE)); + if (mask == 0) + printf(" no config registers\n\n"); + else + printf("\n"); +} + +/*====================================================================*/ + +#define MAX_SOCKS 8 + +int main(int argc, char *argv[]) +{ + int i, j, nfn, fd, ret; + u_int mask; + ds_ioctl_arg_t arg; + +#ifndef __BEOS__ + major = lookup_dev("pcmcia"); + if (major < 0) { + fprintf(stderr, "no pcmcia driver in /proc/devices\n"); + exit(EXIT_FAILURE); + } +#endif + + for (i = 0; i < MAX_SOCKS; i++) { + fd = open_sock(i); + if (fd < 0) break; + + arg.tuple.TupleDataMax = sizeof(arg.tuple_parse.data); + arg.tuple.Attributes = TUPLE_RETURN_COMMON; + arg.tuple.DesiredTuple = CISTPL_LONGLINK_MFC; + arg.tuple.TupleOffset = 0; + if (ioctl(fd, DS_GET_FIRST_TUPLE, &arg) == 0) { + ioctl(fd, DS_GET_TUPLE_DATA, &arg); + ioctl(fd, DS_PARSE_TUPLE, &arg); + nfn = arg.tuple_parse.parse.longlink_mfc.nfn; + } else { + nfn = 1; + arg.tuple.DesiredTuple = CISTPL_DEVICE; + ret = ioctl(fd, DS_GET_FIRST_TUPLE, &arg); + if (ret != 0) { + if (errno != ENODEV) perror("ioctl()"); + continue; + } + } + + arg.tuple.DesiredTuple = CISTPL_CONFIG; + + for (j = 0; j < nfn; j++) { + printf("Socket %d function %d:\n", i, j); + if (ioctl(fd, DS_GET_NEXT_TUPLE, &arg) != 0) { + printf(" no config tuple: %s\n\n", strerror(errno)); + continue; + } + ioctl(fd, DS_GET_TUPLE_DATA, &arg); + ioctl(fd, DS_PARSE_TUPLE, &arg); + printf(" Config register base = %#4.4x, mask = %#4.4x\n", + arg.tuple_parse.parse.config.base, + arg.tuple_parse.parse.config.rmask[0]); + mask = arg.tuple_parse.parse.config.rmask[0]; + dump_all(fd, j, (nfn > 1), mask); + } + + } + return 0; +}