- Kai Germaschewski: ymfpci cleanups and resource leak fixes
[davej-history.git] / drivers / pcmcia / cardbus.c
blob3a83b10c8dc0f3c400bca503ac0a770690b5ef1f
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/string.h>
54 #include <linux/malloc.h>
55 #include <linux/mm.h>
56 #include <linux/pci.h>
57 #include <linux/ioport.h>
58 #include <asm/irq.h>
59 #include <asm/io.h>
61 #define IN_CARD_SERVICES
62 #include <pcmcia/version.h>
63 #include <pcmcia/cs_types.h>
64 #include <pcmcia/ss.h>
65 #include <pcmcia/cs.h>
66 #include <pcmcia/bulkmem.h>
67 #include <pcmcia/cistpl.h>
68 #include "cs_internal.h"
69 #include "rsrc_mgr.h"
71 #ifdef PCMCIA_DEBUG
72 static int pc_debug = PCMCIA_DEBUG;
73 #endif
75 /*====================================================================*/
77 #define FIND_FIRST_BIT(n) ((n) - ((n) & ((n)-1)))
79 #define pci_readb pci_read_config_byte
80 #define pci_writeb pci_write_config_byte
81 #define pci_readw pci_read_config_word
82 #define pci_writew pci_write_config_word
83 #define pci_readl pci_read_config_dword
84 #define pci_writel pci_write_config_dword
86 /* Offsets in the Expansion ROM Image Header */
87 #define ROM_SIGNATURE 0x0000 /* 2 bytes */
88 #define ROM_DATA_PTR 0x0018 /* 2 bytes */
90 /* Offsets in the CardBus PC Card Data Structure */
91 #define PCDATA_SIGNATURE 0x0000 /* 4 bytes */
92 #define PCDATA_VPD_PTR 0x0008 /* 2 bytes */
93 #define PCDATA_LENGTH 0x000a /* 2 bytes */
94 #define PCDATA_REVISION 0x000c
95 #define PCDATA_IMAGE_SZ 0x0010 /* 2 bytes */
96 #define PCDATA_ROM_LEVEL 0x0012 /* 2 bytes */
97 #define PCDATA_CODE_TYPE 0x0014
98 #define PCDATA_INDICATOR 0x0015
100 typedef struct cb_config_t {
101 struct pci_dev dev;
102 } cb_config_t;
104 /*=====================================================================
106 Expansion ROM's have a special layout, and pointers specify an
107 image number and an offset within that image. xlate_rom_addr()
108 converts an image/offset address to an absolute offset from the
109 ROM's base address.
111 =====================================================================*/
113 static u_int xlate_rom_addr(u_char * b, u_int addr)
115 u_int img = 0, ofs = 0, sz;
116 u_short data;
117 while ((readb(b) == 0x55) && (readb(b + 1) == 0xaa)) {
118 if (img == (addr >> 28))
119 return (addr & 0x0fffffff) + ofs;
120 data = readb(b + ROM_DATA_PTR) + (readb(b + ROM_DATA_PTR + 1) << 8);
121 sz = 512 * (readb(b + data + PCDATA_IMAGE_SZ) +
122 (readb(b + data + PCDATA_IMAGE_SZ + 1) << 8));
123 if ((sz == 0) || (readb(b + data + PCDATA_INDICATOR) & 0x80))
124 break;
125 b += sz;
126 ofs += sz;
127 img++;
129 return 0;
132 /*=====================================================================
134 These are similar to setup_cis_mem and release_cis_mem for 16-bit
135 cards. The "result" that is used externally is the cb_cis_virt
136 pointer in the socket_info_t structure.
138 =====================================================================*/
140 void cb_release_cis_mem(socket_info_t * s)
142 if (s->cb_cis_virt) {
143 DEBUG(1, "cs: cb_release_cis_mem()\n");
144 iounmap(s->cb_cis_virt);
145 s->cb_cis_virt = NULL;
146 s->cb_cis_res = 0;
150 static int cb_setup_cis_mem(socket_info_t * s, struct pci_dev *dev, struct resource *res)
152 unsigned int start, size;
154 if (res == s->cb_cis_res)
155 return 0;
157 if (s->cb_cis_res)
158 cb_release_cis_mem(s);
160 start = res->start;
161 size = res->end - start + 1;
162 s->cb_cis_virt = ioremap(start, size);
164 if (!s->cb_cis_virt)
165 return -1;
167 s->cb_cis_res = res;
169 return 0;
172 /*=====================================================================
174 This is used by the CIS processing code to read CIS information
175 from a CardBus device.
177 =====================================================================*/
179 void read_cb_mem(socket_info_t * s, u_char fn, int space,
180 u_int addr, u_int len, void *ptr)
182 struct pci_dev *dev;
183 struct resource *res;
185 DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len);
187 if (!s->cb_config)
188 goto fail;
190 dev = &s->cb_config[fn].dev;
192 /* Config space? */
193 if (space == 0) {
194 if (addr + len > 0x100)
195 goto fail;
196 for (; len; addr++, ptr++, len--)
197 pci_readb(dev, addr, (u_char *) ptr);
198 return;
201 res = dev->resource + space - 1;
202 if (!res->flags)
203 goto fail;
205 if (cb_setup_cis_mem(s, dev, res) != 0)
206 goto fail;
208 if (space == 7) {
209 addr = xlate_rom_addr(s->cb_cis_virt, addr);
210 if (addr == 0)
211 goto fail;
214 if (addr + len > res->end - res->start)
215 goto fail;
217 memcpy_fromio(ptr, s->cb_cis_virt + addr, len);
218 return;
220 fail:
221 memset(ptr, 0xff, len);
222 return;
225 /*=====================================================================
227 cb_alloc() and cb_free() allocate and free the kernel data
228 structures for a Cardbus device, and handle the lowest level PCI
229 device setup issues.
231 =====================================================================*/
233 int cb_alloc(socket_info_t * s)
235 struct pci_bus *bus;
236 struct pci_dev tmp;
237 u_short vend, v, dev;
238 u_char i, hdr, fn;
239 cb_config_t *c;
240 int irq;
242 bus = s->cap.cb_dev->subordinate;
243 memset(&tmp, 0, sizeof(tmp));
244 tmp.bus = bus;
245 tmp.sysdata = bus->sysdata;
246 tmp.devfn = 0;
248 pci_readw(&tmp, PCI_VENDOR_ID, &vend);
249 pci_readw(&tmp, PCI_DEVICE_ID, &dev);
250 printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
251 "device 0x%04x\n", bus->number, vend, dev);
253 pci_readb(&tmp, PCI_HEADER_TYPE, &hdr);
254 fn = 1;
255 if (hdr & 0x80) {
256 do {
257 tmp.devfn = fn;
258 if (pci_readw(&tmp, PCI_VENDOR_ID, &v) || !v || v == 0xffff)
259 break;
260 fn++;
261 } while (fn < 8);
263 s->functions = fn;
265 c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC);
266 if (!c)
267 return CS_OUT_OF_RESOURCE;
268 memset(c, 0, fn * sizeof(struct cb_config_t));
270 irq = s->cap.pci_irq;
271 for (i = 0; i < fn; i++) {
272 struct pci_dev *dev = &c[i].dev;
273 u8 irq_pin;
274 int r;
276 dev->bus = bus;
277 dev->sysdata = bus->sysdata;
278 dev->devfn = i;
279 dev->vendor = vend;
280 pci_readw(dev, PCI_DEVICE_ID, &dev->device);
281 dev->hdr_type = hdr & 0x7f;
283 pci_setup_device(dev);
285 /* FIXME: Do we need to enable the expansion ROM? */
286 for (r = 0; r < 7; r++) {
287 struct resource *res = dev->resource + r;
288 if (res->flags)
289 pci_assign_resource(dev, r);
291 pci_enable_device(dev); /* XXX check return */
293 /* Does this function have an interrupt at all? */
294 pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
295 if (irq_pin) {
296 dev->irq = irq;
297 pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
300 pci_insert_device(dev, bus);
303 s->cb_config = c;
304 s->irq.AssignedIRQ = irq;
305 return CS_SUCCESS;
308 void cb_free(socket_info_t * s)
310 cb_config_t *c = s->cb_config;
312 if (c) {
313 int i;
315 s->cb_config = NULL;
316 for (i = 0 ; i < s->functions ; i++)
317 pci_remove_device(&c[i].dev);
319 kfree(c);
320 printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
324 /*=====================================================================
326 cb_config() has the job of allocating all system resources that
327 a Cardbus card requires. Rather than using the CIS (which seems
328 to not always be present), it treats the card as an ordinary PCI
329 device, and probes the base address registers to determine each
330 function's IO and memory space needs.
332 It is called from the RequestIO card service.
334 ======================================================================*/
336 int cb_config(socket_info_t * s)
338 return CS_SUCCESS;
341 /*======================================================================
343 cb_release() releases all the system resources (IO and memory
344 space, and interrupt) committed for a Cardbus card by a prior call
345 to cb_config().
347 It is called from the ReleaseIO() service.
349 ======================================================================*/
351 void cb_release(socket_info_t * s)
353 DEBUG(0, "cs: cb_release(bus %d)\n", s->cap.cb_dev->subordinate->number);
356 /*=====================================================================
358 cb_enable() has the job of configuring a socket for a Cardbus
359 card, and initializing the card's PCI configuration registers.
361 It first sets up the Cardbus bridge windows, for IO and memory
362 accesses. Then, it initializes each card function's base address
363 registers, interrupt line register, and command register.
365 It is called as part of the RequestConfiguration card service.
366 It should be called after a previous call to cb_config() (via the
367 RequestIO service).
369 ======================================================================*/
371 void cb_enable(socket_info_t * s)
373 struct pci_dev *dev;
374 u_char i;
376 DEBUG(0, "cs: cb_enable(bus %d)\n", s->cap.cb_dev->subordinate->number);
378 /* Configure bridge */
379 cb_release_cis_mem(s);
381 /* Set up PCI interrupt and command registers */
382 for (i = 0; i < s->functions; i++) {
383 dev = &s->cb_config[i].dev;
384 pci_writeb(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
385 PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
386 pci_writeb(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
389 if (s->irq.AssignedIRQ) {
390 for (i = 0; i < s->functions; i++) {
391 dev = &s->cb_config[i].dev;
392 pci_writeb(dev, PCI_INTERRUPT_LINE, s->irq.AssignedIRQ);
394 s->socket.io_irq = s->irq.AssignedIRQ;
395 s->ss_entry->set_socket(s->sock, &s->socket);
399 /*======================================================================
401 cb_disable() unconfigures a Cardbus card previously set up by
402 cb_enable().
404 It is called from the ReleaseConfiguration service.
406 ======================================================================*/
408 void cb_disable(socket_info_t * s)
410 DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cb_dev->subordinate->number);
412 /* Turn off bridge windows */
413 cb_release_cis_mem(s);