- pre5:
[davej-history.git] / drivers / pcmcia / cardbus.c
blob7def8a493572db3dc85e65921b2f84b21382a592
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 #ifndef PCMCIA_DEBUG
62 #define PCMCIA_DEBUG 1
63 #endif
64 static int pc_debug = PCMCIA_DEBUG;
66 #define IN_CARD_SERVICES
67 #include <pcmcia/version.h>
68 #include <pcmcia/cs_types.h>
69 #include <pcmcia/ss.h>
70 #include <pcmcia/cs.h>
71 #include <pcmcia/bulkmem.h>
72 #include <pcmcia/cistpl.h>
73 #include "cs_internal.h"
74 #include "rsrc_mgr.h"
76 /*====================================================================*/
78 #define FIND_FIRST_BIT(n) ((n) - ((n) & ((n)-1)))
80 #define pci_readb pci_read_config_byte
81 #define pci_writeb pci_write_config_byte
82 #define pci_readw pci_read_config_word
83 #define pci_writew pci_write_config_word
84 #define pci_readl pci_read_config_dword
85 #define pci_writel pci_write_config_dword
87 /* Offsets in the Expansion ROM Image Header */
88 #define ROM_SIGNATURE 0x0000 /* 2 bytes */
89 #define ROM_DATA_PTR 0x0018 /* 2 bytes */
91 /* Offsets in the CardBus PC Card Data Structure */
92 #define PCDATA_SIGNATURE 0x0000 /* 4 bytes */
93 #define PCDATA_VPD_PTR 0x0008 /* 2 bytes */
94 #define PCDATA_LENGTH 0x000a /* 2 bytes */
95 #define PCDATA_REVISION 0x000c
96 #define PCDATA_IMAGE_SZ 0x0010 /* 2 bytes */
97 #define PCDATA_ROM_LEVEL 0x0012 /* 2 bytes */
98 #define PCDATA_CODE_TYPE 0x0014
99 #define PCDATA_INDICATOR 0x0015
101 typedef struct cb_config_t {
102 struct pci_dev dev;
103 } cb_config_t;
105 /*=====================================================================
107 Expansion ROM's have a special layout, and pointers specify an
108 image number and an offset within that image. xlate_rom_addr()
109 converts an image/offset address to an absolute offset from the
110 ROM's base address.
112 =====================================================================*/
114 static u_int xlate_rom_addr(u_char * b, u_int addr)
116 u_int img = 0, ofs = 0, sz;
117 u_short data;
118 while ((readb(b) == 0x55) && (readb(b + 1) == 0xaa)) {
119 if (img == (addr >> 28))
120 return (addr & 0x0fffffff) + ofs;
121 data = readb(b + ROM_DATA_PTR) + (readb(b + ROM_DATA_PTR + 1) << 8);
122 sz = 512 * (readb(b + data + PCDATA_IMAGE_SZ) +
123 (readb(b + data + PCDATA_IMAGE_SZ + 1) << 8));
124 if ((sz == 0) || (readb(b + data + PCDATA_INDICATOR) & 0x80))
125 break;
126 b += sz;
127 ofs += sz;
128 img++;
130 return 0;
133 /*=====================================================================
135 These are similar to setup_cis_mem and release_cis_mem for 16-bit
136 cards. The "result" that is used externally is the cb_cis_virt
137 pointer in the socket_info_t structure.
139 =====================================================================*/
141 void cb_release_cis_mem(socket_info_t * s)
143 if (s->cb_cis_virt) {
144 DEBUG(1, "cs: cb_release_cis_mem()\n");
145 iounmap(s->cb_cis_virt);
146 s->cb_cis_virt = NULL;
147 s->cb_cis_res = 0;
151 static int cb_setup_cis_mem(socket_info_t * s, struct pci_dev *dev, struct resource *res)
153 unsigned int start, size;
155 if (res == s->cb_cis_res)
156 return 0;
158 if (s->cb_cis_res)
159 cb_release_cis_mem(s);
161 start = res->start;
162 size = res->end - start + 1;
163 s->cb_cis_virt = ioremap(start, size);
165 if (!s->cb_cis_virt)
166 return -1;
168 s->cb_cis_res = res;
170 return 0;
173 /*=====================================================================
175 This is used by the CIS processing code to read CIS information
176 from a CardBus device.
178 =====================================================================*/
180 void read_cb_mem(socket_info_t * s, u_char fn, int space,
181 u_int addr, u_int len, void *ptr)
183 struct pci_dev *dev;
184 struct resource *res;
186 DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len);
188 if (!s->cb_config)
189 goto fail;
191 dev = &s->cb_config[fn].dev;
193 /* Config space? */
194 if (space == 0) {
195 if (addr + len > 0x100)
196 goto fail;
197 for (; len; addr++, ptr++, len--)
198 pci_readb(dev, addr, (u_char *) ptr);
199 return;
202 res = dev->resource + space - 1;
203 if (!res->flags)
204 goto fail;
206 if (cb_setup_cis_mem(s, dev, res) != 0)
207 goto fail;
209 if (space == 7) {
210 addr = xlate_rom_addr(s->cb_cis_virt, addr);
211 if (addr == 0)
212 goto fail;
215 if (addr + len > res->end - res->start)
216 goto fail;
218 memcpy_fromio(ptr, s->cb_cis_virt + addr, len);
219 return;
221 fail:
222 memset(ptr, 0xff, len);
223 return;
226 /*=====================================================================
228 cb_alloc() and cb_free() allocate and free the kernel data
229 structures for a Cardbus device, and handle the lowest level PCI
230 device setup issues.
232 =====================================================================*/
234 int cb_alloc(socket_info_t * s)
236 struct pci_bus *bus;
237 struct pci_dev tmp;
238 u_short vend, v, dev;
239 u_char i, hdr, fn;
240 cb_config_t *c;
241 int irq;
243 bus = s->cap.cb_dev->subordinate;
244 memset(&tmp, 0, sizeof(tmp));
245 tmp.bus = bus;
246 tmp.sysdata = bus->sysdata;
247 tmp.devfn = 0;
249 pci_readw(&tmp, PCI_VENDOR_ID, &vend);
250 pci_readw(&tmp, PCI_DEVICE_ID, &dev);
251 printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
252 "device 0x%04x\n", bus->number, vend, dev);
254 pci_readb(&tmp, PCI_HEADER_TYPE, &hdr);
255 fn = 1;
256 if (hdr & 0x80) {
257 do {
258 tmp.devfn = fn;
259 if (pci_readw(&tmp, PCI_VENDOR_ID, &v) || !v || v == 0xffff)
260 break;
261 fn++;
262 } while (fn < 8);
264 s->functions = fn;
266 c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC);
267 if (!c)
268 return CS_OUT_OF_RESOURCE;
269 memset(c, 0, fn * sizeof(struct cb_config_t));
271 irq = s->cap.pci_irq;
272 for (i = 0; i < fn; i++) {
273 struct pci_dev *dev = &c[i].dev;
274 u8 irq_pin;
275 int r;
277 dev->bus = bus;
278 dev->sysdata = bus->sysdata;
279 dev->devfn = i;
280 dev->vendor = vend;
281 pci_readw(dev, PCI_DEVICE_ID, &dev->device);
282 dev->hdr_type = hdr & 0x7f;
284 pci_setup_device(dev);
286 /* FIXME: Do we need to enable the expansion ROM? */
287 for (r = 0; r < 7; r++) {
288 struct resource *res = dev->resource + r;
289 if (res->flags)
290 pci_assign_resource(dev, r);
292 pci_enable_device(dev); /* XXX check return */
294 /* Does this function have an interrupt at all? */
295 pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
296 if (irq_pin) {
297 dev->irq = irq;
298 pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
301 pci_insert_device(dev, bus);
304 s->cb_config = c;
305 s->irq.AssignedIRQ = irq;
306 return CS_SUCCESS;
309 void cb_free(socket_info_t * s)
311 cb_config_t *c = s->cb_config;
313 if (c) {
314 int i;
316 s->cb_config = NULL;
317 for (i = 0 ; i < s->functions ; i++)
318 pci_remove_device(&c[i].dev);
320 kfree(c);
321 printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
325 /*=====================================================================
327 cb_config() has the job of allocating all system resources that
328 a Cardbus card requires. Rather than using the CIS (which seems
329 to not always be present), it treats the card as an ordinary PCI
330 device, and probes the base address registers to determine each
331 function's IO and memory space needs.
333 It is called from the RequestIO card service.
335 ======================================================================*/
337 int cb_config(socket_info_t * s)
339 return CS_SUCCESS;
342 /*======================================================================
344 cb_release() releases all the system resources (IO and memory
345 space, and interrupt) committed for a Cardbus card by a prior call
346 to cb_config().
348 It is called from the ReleaseIO() service.
350 ======================================================================*/
352 void cb_release(socket_info_t * s)
354 DEBUG(0, "cs: cb_release(bus %d)\n", s->cap.cb_dev->subordinate->number);
357 /*=====================================================================
359 cb_enable() has the job of configuring a socket for a Cardbus
360 card, and initializing the card's PCI configuration registers.
362 It first sets up the Cardbus bridge windows, for IO and memory
363 accesses. Then, it initializes each card function's base address
364 registers, interrupt line register, and command register.
366 It is called as part of the RequestConfiguration card service.
367 It should be called after a previous call to cb_config() (via the
368 RequestIO service).
370 ======================================================================*/
372 void cb_enable(socket_info_t * s)
374 struct pci_dev *dev;
375 u_char i, bus = s->cap.cb_dev->subordinate->number;
377 DEBUG(0, "cs: cb_enable(bus %d)\n", bus);
379 /* Configure bridge */
380 cb_release_cis_mem(s);
382 /* Set up PCI interrupt and command registers */
383 for (i = 0; i < s->functions; i++) {
384 dev = &s->cb_config[i].dev;
385 pci_writeb(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
386 PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
387 pci_writeb(dev, PCI_CACHE_LINE_SIZE, 8);
390 if (s->irq.AssignedIRQ) {
391 for (i = 0; i < s->functions; i++) {
392 dev = &s->cb_config[i].dev;
393 pci_writeb(dev, PCI_INTERRUPT_LINE, s->irq.AssignedIRQ);
395 s->socket.io_irq = s->irq.AssignedIRQ;
396 s->ss_entry->set_socket(s->sock, &s->socket);
400 /*======================================================================
402 cb_disable() unconfigures a Cardbus card previously set up by
403 cb_enable().
405 It is called from the ReleaseConfiguration service.
407 ======================================================================*/
409 void cb_disable(socket_info_t * s)
411 DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cb_dev->subordinate->number);
413 /* Turn off bridge windows */
414 cb_release_cis_mem(s);