- pre2
[davej-history.git] / drivers / pcmcia / cardbus.c
blob0216ed2b3ade8cdd805d4820cd4bdce72095d74c
1 /*======================================================================
3 Cardbus device configuration
5 cardbus.c 1.63 1999/11/08 20:47:02
7 The contents of this file are subject to the Mozilla Public
8 License Version 1.1 (the "License"); you may not use this file
9 except in compliance with the License. You may obtain a copy of
10 the License at http://www.mozilla.org/MPL/
12 Software distributed under the License is distributed on an "AS
13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 implied. See the License for the specific language governing
15 rights and limitations under the License.
17 The initial developer of the original code is David A. Hinds
18 <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU Public License version 2 (the "GPL"), in which
23 case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
32 These routines handle allocating resources for Cardbus cards, as
33 well as setting up and shutting down Cardbus sockets. They are
34 called from cs.c in response to Request/ReleaseConfiguration and
35 Request/ReleaseIO calls.
37 ======================================================================*/
40 * This file is going away. Cardbus handling has been re-written to be
41 * more of a PCI bridge thing, and the PCI code basically does all the
42 * resource handling. This has wrappers to make the rest of the PCMCIA
43 * subsystem not notice that it's not here any more.
45 * Linus, Jan 2000
49 #define __NO_VERSION__
51 #include <linux/module.h>
52 #include <linux/kernel.h>
53 #include <linux/config.h>
54 #include <linux/string.h>
55 #include <linux/malloc.h>
56 #include <linux/mm.h>
57 #include <linux/pci.h>
58 #include <linux/ioport.h>
59 #include <asm/irq.h>
60 #include <asm/io.h>
62 #ifndef PCMCIA_DEBUG
63 #define PCMCIA_DEBUG 1
64 #endif
65 static int pc_debug = PCMCIA_DEBUG;
67 #define IN_CARD_SERVICES
68 #include <pcmcia/version.h>
69 #include <pcmcia/cs_types.h>
70 #include <pcmcia/ss.h>
71 #include <pcmcia/cs.h>
72 #include <pcmcia/bulkmem.h>
73 #include <pcmcia/cistpl.h>
74 #include "cs_internal.h"
75 #include "rsrc_mgr.h"
77 /*====================================================================*/
79 #define FIND_FIRST_BIT(n) ((n) - ((n) & ((n)-1)))
81 #define pci_readb pci_read_config_byte
82 #define pci_writeb pci_write_config_byte
83 #define pci_readw pci_read_config_word
84 #define pci_writew pci_write_config_word
85 #define pci_readl pci_read_config_dword
86 #define pci_writel pci_write_config_dword
88 /* Offsets in the Expansion ROM Image Header */
89 #define ROM_SIGNATURE 0x0000 /* 2 bytes */
90 #define ROM_DATA_PTR 0x0018 /* 2 bytes */
92 /* Offsets in the CardBus PC Card Data Structure */
93 #define PCDATA_SIGNATURE 0x0000 /* 4 bytes */
94 #define PCDATA_VPD_PTR 0x0008 /* 2 bytes */
95 #define PCDATA_LENGTH 0x000a /* 2 bytes */
96 #define PCDATA_REVISION 0x000c
97 #define PCDATA_IMAGE_SZ 0x0010 /* 2 bytes */
98 #define PCDATA_ROM_LEVEL 0x0012 /* 2 bytes */
99 #define PCDATA_CODE_TYPE 0x0014
100 #define PCDATA_INDICATOR 0x0015
102 typedef struct cb_config_t {
103 struct pci_dev dev;
104 } cb_config_t;
106 /*=====================================================================
108 Expansion ROM's have a special layout, and pointers specify an
109 image number and an offset within that image. xlate_rom_addr()
110 converts an image/offset address to an absolute offset from the
111 ROM's base address.
113 =====================================================================*/
115 static u_int xlate_rom_addr(u_char * b, u_int addr)
117 u_int img = 0, ofs = 0, sz;
118 u_short data;
119 while ((readb(b) == 0x55) && (readb(b + 1) == 0xaa)) {
120 if (img == (addr >> 28))
121 return (addr & 0x0fffffff) + ofs;
122 data = readb(b + ROM_DATA_PTR) + (readb(b + ROM_DATA_PTR + 1) << 8);
123 sz = 512 * (readb(b + data + PCDATA_IMAGE_SZ) +
124 (readb(b + data + PCDATA_IMAGE_SZ + 1) << 8));
125 if ((sz == 0) || (readb(b + data + PCDATA_INDICATOR) & 0x80))
126 break;
127 b += sz;
128 ofs += sz;
129 img++;
131 return 0;
134 /*=====================================================================
136 These are similar to setup_cis_mem and release_cis_mem for 16-bit
137 cards. The "result" that is used externally is the cb_cis_virt
138 pointer in the socket_info_t structure.
140 =====================================================================*/
142 void cb_release_cis_mem(socket_info_t * s)
144 if (s->cb_cis_virt) {
145 DEBUG(1, "cs: cb_release_cis_mem()\n");
146 iounmap(s->cb_cis_virt);
147 s->cb_cis_virt = NULL;
148 s->cb_cis_res = 0;
152 static int cb_setup_cis_mem(socket_info_t * s, struct pci_dev *dev, struct resource *res)
154 unsigned int start, size;
156 if (res == s->cb_cis_res)
157 return 0;
159 if (s->cb_cis_res)
160 cb_release_cis_mem(s);
162 start = res->start;
163 size = res->end - start + 1;
164 s->cb_cis_virt = ioremap(start, size);
166 if (!s->cb_cis_virt)
167 return -1;
169 s->cb_cis_res = res;
171 return 0;
174 /*=====================================================================
176 This is used by the CIS processing code to read CIS information
177 from a CardBus device.
179 =====================================================================*/
181 void read_cb_mem(socket_info_t * s, u_char fn, int space,
182 u_int addr, u_int len, void *ptr)
184 struct pci_dev *dev;
185 struct resource *res;
187 DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len);
189 if (!s->cb_config)
190 goto fail;
192 dev = &s->cb_config[fn].dev;
194 /* Config space? */
195 if (space == 0) {
196 if (addr + len > 0x100)
197 goto fail;
198 for (; len; addr++, ptr++, len--)
199 pci_readb(dev, addr, (u_char *) ptr);
200 return;
203 res = dev->resource + space - 1;
204 if (!res->flags)
205 goto fail;
207 if (cb_setup_cis_mem(s, dev, res) != 0)
208 goto fail;
210 if (space == 7) {
211 addr = xlate_rom_addr(s->cb_cis_virt, addr);
212 if (addr == 0)
213 goto fail;
216 if (addr + len > res->end - res->start)
217 goto fail;
219 memcpy_fromio(ptr, s->cb_cis_virt + addr, len);
220 return;
222 fail:
223 memset(ptr, 0xff, len);
224 return;
227 /*=====================================================================
229 cb_alloc() and cb_free() allocate and free the kernel data
230 structures for a Cardbus device, and handle the lowest level PCI
231 device setup issues.
233 =====================================================================*/
235 int cb_alloc(socket_info_t * s)
237 struct pci_bus *bus;
238 struct pci_dev tmp;
239 u_short vend, v, dev;
240 u_char i, hdr, fn;
241 cb_config_t *c;
242 int irq;
244 bus = s->cap.cb_dev->subordinate;
245 memset(&tmp, 0, sizeof(tmp));
246 tmp.bus = bus;
247 tmp.sysdata = bus->sysdata;
248 tmp.devfn = 0;
250 pci_readw(&tmp, PCI_VENDOR_ID, &vend);
251 pci_readw(&tmp, PCI_DEVICE_ID, &dev);
252 printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
253 "device 0x%04x\n", bus->number, vend, dev);
255 pci_readb(&tmp, PCI_HEADER_TYPE, &hdr);
256 fn = 1;
257 if (hdr & 0x80) {
258 do {
259 tmp.devfn = fn;
260 if (pci_readw(&tmp, PCI_VENDOR_ID, &v) || !v || v == 0xffff)
261 break;
262 fn++;
263 } while (fn < 8);
265 s->functions = fn;
267 c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC);
268 if (!c)
269 return CS_OUT_OF_RESOURCE;
270 memset(c, 0, fn * sizeof(struct cb_config_t));
272 irq = s->cap.pci_irq;
273 for (i = 0; i < fn; i++) {
274 struct pci_dev *dev = &c[i].dev;
275 u8 irq_pin;
276 int r;
278 dev->bus = bus;
279 dev->sysdata = bus->sysdata;
280 dev->devfn = i;
281 dev->vendor = vend;
282 pci_readw(dev, PCI_DEVICE_ID, &dev->device);
283 dev->hdr_type = hdr & 0x7f;
285 pci_setup_device(dev);
287 /* FIXME: Do we need to enable the expansion ROM? */
288 for (r = 0; r < 7; r++) {
289 struct resource *res = dev->resource + r;
290 if (res->flags)
291 pci_assign_resource(dev, r);
293 pci_enable_device(dev); /* XXX check return */
295 /* Does this function have an interrupt at all? */
296 pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
297 if (irq_pin) {
298 dev->irq = irq;
299 pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
302 pci_insert_device(dev, bus);
305 s->cb_config = c;
306 s->irq.AssignedIRQ = irq;
307 return CS_SUCCESS;
310 void cb_free(socket_info_t * s)
312 cb_config_t *c = s->cb_config;
314 if (c) {
315 int i;
317 s->cb_config = NULL;
318 for (i = 0 ; i < s->functions ; i++)
319 pci_remove_device(&c[i].dev);
321 kfree(c);
322 printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
326 /*=====================================================================
328 cb_config() has the job of allocating all system resources that
329 a Cardbus card requires. Rather than using the CIS (which seems
330 to not always be present), it treats the card as an ordinary PCI
331 device, and probes the base address registers to determine each
332 function's IO and memory space needs.
334 It is called from the RequestIO card service.
336 ======================================================================*/
338 int cb_config(socket_info_t * s)
340 return CS_SUCCESS;
343 /*======================================================================
345 cb_release() releases all the system resources (IO and memory
346 space, and interrupt) committed for a Cardbus card by a prior call
347 to cb_config().
349 It is called from the ReleaseIO() service.
351 ======================================================================*/
353 void cb_release(socket_info_t * s)
355 DEBUG(0, "cs: cb_release(bus %d)\n", s->cap.cb_dev->subordinate->number);
358 /*=====================================================================
360 cb_enable() has the job of configuring a socket for a Cardbus
361 card, and initializing the card's PCI configuration registers.
363 It first sets up the Cardbus bridge windows, for IO and memory
364 accesses. Then, it initializes each card function's base address
365 registers, interrupt line register, and command register.
367 It is called as part of the RequestConfiguration card service.
368 It should be called after a previous call to cb_config() (via the
369 RequestIO service).
371 ======================================================================*/
373 void cb_enable(socket_info_t * s)
375 struct pci_dev *dev;
376 u_char i, bus = s->cap.cb_dev->subordinate->number;
378 DEBUG(0, "cs: cb_enable(bus %d)\n", bus);
380 /* Configure bridge */
381 cb_release_cis_mem(s);
383 /* Set up PCI interrupt and command registers */
384 for (i = 0; i < s->functions; i++) {
385 dev = &s->cb_config[i].dev;
386 pci_writeb(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
387 PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
388 pci_writeb(dev, PCI_CACHE_LINE_SIZE, 8);
391 if (s->irq.AssignedIRQ) {
392 for (i = 0; i < s->functions; i++) {
393 dev = &s->cb_config[i].dev;
394 pci_writeb(dev, PCI_INTERRUPT_LINE, s->irq.AssignedIRQ);
396 s->socket.io_irq = s->irq.AssignedIRQ;
397 s->ss_entry->set_socket(s->sock, &s->socket);
401 /*======================================================================
403 cb_disable() unconfigures a Cardbus card previously set up by
404 cb_enable().
406 It is called from the ReleaseConfiguration service.
408 ======================================================================*/
410 void cb_disable(socket_info_t * s)
412 DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cb_dev->subordinate->number);
414 /* Turn off bridge windows */
415 cb_release_cis_mem(s);