blob: f573ea04db6f577ca78f90f34ce5638842c57bdc [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * cs_internal.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds
9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
11 *
12 * (C) 1999 David A. Hinds
13 */
14
15#ifndef _LINUX_CS_INTERNAL_H
16#define _LINUX_CS_INTERNAL_H
17
Dominik Brodowski360b65b2006-01-10 20:50:39 +010018#include <linux/kref.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019
Linus Torvalds1da177e2005-04-16 15:20:36 -070020/* Flags in client state */
21#define CLIENT_CONFIG_LOCKED 0x0001
22#define CLIENT_IRQ_REQ 0x0002
23#define CLIENT_IO_REQ 0x0004
24#define CLIENT_UNBOUND 0x0008
25#define CLIENT_STALE 0x0010
Dominik Brodowskie2d40962006-03-02 00:09:29 +010026#define CLIENT_WIN_REQ(i) (0x1<<(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#define CLIENT_CARDBUS 0x8000
28
29#define REGION_MAGIC 0xE3C9
30typedef struct region_t {
31 u_short region_magic;
32 u_short state;
33 dev_info_t dev_info;
Dominik Brodowskifba395e2006-03-31 17:21:06 +020034 struct pcmcia_device *mtd;
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 u_int MediaID;
36 region_info_t info;
37} region_t;
38
39#define REGION_STALE 0x01
40
41/* Each card function gets one of these guys */
42typedef struct config_t {
Dominik Brodowski360b65b2006-01-10 20:50:39 +010043 struct kref ref;
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 u_int state;
45 u_int Attributes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 u_int IntType;
47 u_int ConfigBase;
48 u_char Status, Pin, Copy, Option, ExtStatus;
Linus Torvalds1da177e2005-04-16 15:20:36 -070049 u_int CardValues;
50 io_req_t io;
51 struct {
52 u_int Attributes;
53 } irq;
54} config_t;
55
56struct cis_cache_entry {
57 struct list_head node;
58 unsigned int addr;
59 unsigned int len;
60 unsigned int attr;
61 unsigned char cache[0];
62};
63
64/* Flags in config state */
65#define CONFIG_LOCKED 0x01
66#define CONFIG_IRQ_REQ 0x02
67#define CONFIG_IO_REQ 0x04
68
69/* Flags in socket state */
70#define SOCKET_PRESENT 0x0008
71#define SOCKET_INUSE 0x0010
72#define SOCKET_SUSPEND 0x0080
73#define SOCKET_WIN_REQ(i) (0x0100<<(i))
74#define SOCKET_REGION_INFO 0x4000
75#define SOCKET_CARDBUS 0x8000
76#define SOCKET_CARDBUS_CONFIG 0x10000
77
78static inline int cs_socket_get(struct pcmcia_socket *skt)
79{
80 int ret;
81
82 WARN_ON(skt->state & SOCKET_INUSE);
83
84 ret = try_module_get(skt->owner);
85 if (ret)
86 skt->state |= SOCKET_INUSE;
87 return ret;
88}
89
90static inline void cs_socket_put(struct pcmcia_socket *skt)
91{
92 if (skt->state & SOCKET_INUSE) {
93 skt->state &= ~SOCKET_INUSE;
94 module_put(skt->owner);
95 }
96}
97
Linus Torvalds1da177e2005-04-16 15:20:36 -070098/* In cardbus.c */
99int cb_alloc(struct pcmcia_socket *s);
100void cb_free(struct pcmcia_socket *s);
101int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);
102
103/* In cistpl.c */
Dominik Brodowskie6ea0b9e2005-06-27 16:28:52 -0700104int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 u_int addr, u_int len, void *ptr);
Dominik Brodowskie6ea0b9e2005-06-27 16:28:52 -0700106void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 u_int addr, u_int len, void *ptr);
108void release_cis_mem(struct pcmcia_socket *s);
109void destroy_cis_cache(struct pcmcia_socket *s);
110int verify_cis_cache(struct pcmcia_socket *s);
111int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
112
113/* In rsrc_mgr */
Dominik Brodowskide759142005-09-28 19:41:56 +0200114int pcmcia_validate_mem(struct pcmcia_socket *s);
Dominik Brodowskie6ea0b9e2005-06-27 16:28:52 -0700115struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 struct pcmcia_socket *s);
Dominik Brodowskie6ea0b9e2005-06-27 16:28:52 -0700117int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 unsigned long r_end, struct pcmcia_socket *s);
Dominik Brodowskie6ea0b9e2005-06-27 16:28:52 -0700119struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 int low, struct pcmcia_socket *s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121void release_resource_db(struct pcmcia_socket *s);
122
123/* In socket_sysfs.c */
124extern struct class_interface pccard_sysfs_interface;
125
126/* In cs.c */
127extern struct rw_semaphore pcmcia_socket_list_rwsem;
128extern struct list_head pcmcia_socket_list;
129int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
Dominik Brodowski855cdf12006-01-10 20:48:59 +0100130int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131int pccard_reset_card(struct pcmcia_socket *skt);
Dominik Brodowski855cdf12006-01-10 20:48:59 +0100132int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
134
135struct pcmcia_callback{
136 struct module *owner;
137 int (*event) (struct pcmcia_socket *s, event_t event, int priority);
Dominik Brodowski4ae1cbf2006-11-03 10:54:00 -0500138 void (*requery) (struct pcmcia_socket *s, int new_cis);
Dominik Brodowski8e9e7932006-01-06 00:02:03 +0100139 int (*suspend) (struct pcmcia_socket *s);
140 int (*resume) (struct pcmcia_socket *s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141};
142
143int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
144
145#define cs_socket_name(skt) ((skt)->dev.class_id)
146
147#ifdef DEBUG
148extern int cs_debug_level(int);
149
150#define cs_dbg(skt, lvl, fmt, arg...) do { \
151 if (cs_debug_level(lvl)) \
152 printk(KERN_DEBUG "cs: %s: " fmt, \
153 cs_socket_name(skt) , ## arg); \
154} while (0)
155
156#else
157#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
158#endif
159
160#define cs_err(skt, fmt, arg...) \
161 printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.class_id , ## arg)
162
163#endif /* _LINUX_CS_INTERNAL_H */