]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6.x-PD6729-lkml.patch
- [sparc32] grsec disabled.
[packages/kernel.git] / 2.6.x-PD6729-lkml.patch
CommitLineData
a494c824 1diff -ruN linux/drivers/pcmcia.orig/Kconfig linux/drivers/pcmcia/Kconfig
2--- linux/drivers/pcmcia.orig/Kconfig 2004-01-09 15:59:48.000000000 +0900
3+++ linux/drivers/pcmcia/Kconfig 2004-01-13 21:28:09.000000000 +0900
4@@ -50,6 +50,13 @@
5 depends on YENTA
6 default y if YENTA
7
8+config PD6729
9+ tristate "Cirrus PD6729 compatible bridge support"
10+ depends on PCMCIA && PCI
11+ help
12+ This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge device,
13+ found in some older laptops and PCMCIA card readers.
14+
15 config I82092
16 tristate "i82092 compatible bridge support"
17 depends on PCMCIA && PCI
18diff -ruN linux/drivers/pcmcia.orig/Makefile linux/drivers/pcmcia/Makefile
19--- linux/drivers/pcmcia.orig/Makefile 2004-01-09 15:59:55.000000000 +0900
20+++ linux/drivers/pcmcia/Makefile 2004-01-13 21:28:09.000000000 +0900
21@@ -5,6 +5,7 @@
22 obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o
23 obj-$(CONFIG_YENTA) += yenta_socket.o
24
25+obj-$(CONFIG_PD6729) += pd6729.o
26 obj-$(CONFIG_I82365) += i82365.o
27 obj-$(CONFIG_I82092) += i82092.o
28 obj-$(CONFIG_TCIC) += tcic.o
29diff -ruN linux/drivers/pcmcia.orig/pd6729.c linux/drivers/pcmcia/pd6729.c
30--- linux/drivers/pcmcia.orig/pd6729.c 1970-01-01 09:00:00.000000000 +0900
31+++ linux/drivers/pcmcia/pd6729.c 2004-02-01 11:40:35.893397648 +0900
32@@ -0,0 +1,759 @@
33+/*
34+ * Driver for the Cirrus PD6729 PCI-PCMCIA bridge.
35+ *
36+ * Based on the i82092.c driver.
37+ *
38+ * This software may be used and distributed according to the terms of
39+ * the GNU General Public License, incorporated herein by reference.
40+ */
41+
42+#include <linux/kernel.h>
43+#include <linux/config.h>
44+#include <linux/module.h>
45+#include <linux/pci.h>
46+#include <linux/init.h>
47+#include <linux/workqueue.h>
48+#include <linux/interrupt.h>
49+#include <linux/device.h>
50+
51+#include <pcmcia/cs_types.h>
52+#include <pcmcia/ss.h>
53+#include <pcmcia/cs.h>
54+
55+#include <asm/system.h>
56+#include <asm/io.h>
57+
58+#include "pd6729.h"
59+#include "i82365.h"
60+#include "cirrus.h"
61+
62+MODULE_LICENSE("GPL");
63+
64+/* PCI core routines */
65+static struct pci_device_id pd6729_pci_ids[] = {
66+ {
67+ .vendor = PCI_VENDOR_ID_CIRRUS,
68+ .device = PCI_DEVICE_ID_CIRRUS_6729,
69+ .subvendor = PCI_ANY_ID,
70+ .subdevice = PCI_ANY_ID,
71+ },
72+ {}
73+};
74+MODULE_DEVICE_TABLE(pci, pd6729_pci_ids);
75+
76+static int pd6729_socket_suspend (struct pci_dev *dev, u32 state)
77+{
78+ return pcmcia_socket_dev_suspend(&dev->dev, state);
79+}
80+
81+static int pd6729_socket_resume (struct pci_dev *dev)
82+{
83+ return pcmcia_socket_dev_resume(&dev->dev);
84+}
85+
86+static struct pci_driver pd6729_pci_drv = {
87+ .name = "pd6729",
88+ .id_table = pd6729_pci_ids,
89+ .probe = pd6729_pci_probe,
90+ .remove = __devexit_p(pd6729_pci_remove),
91+ .suspend = pd6729_socket_suspend,
92+ .resume = pd6729_socket_resume,
93+};
94+
95+
96+/* the pccard structure and its functions */
97+static struct pccard_operations pd6729_operations = {
98+ .init = pd6729_init,
99+ .suspend = pd6729_suspend,
100+ .get_status = pd6729_get_status,
101+ .get_socket = pd6729_get_socket,
102+ .set_socket = pd6729_set_socket,
103+ .set_io_map = pd6729_set_io_map,
104+ .set_mem_map = pd6729_set_mem_map,
105+};
106+
107+/* The card can do upto 4 sockets, allocate a structure for each of them */
108+
109+struct socket_info {
110+ int number;
111+ int card_state; /* 0 = no socket,
112+ 1 = empty socket,
113+ 2 = card but not initialized,
114+ 3 = operational card */
115+ int io_base; /* base io address of the socket */
116+
117+ struct pcmcia_socket socket;
118+ struct pci_dev *dev; /* The PCI device for the socket */
119+};
120+
121+#define MAX_SOCKETS 4
122+static struct socket_info sockets[MAX_SOCKETS];
123+static int socket_count; /* shortcut */
124+
125+static int __devinit pd6729_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
126+{
127+ int i, ret;
128+ char configbyte;
129+
130+ if ((ret = pci_enable_device(dev)))
131+ return ret;
132+
133+ socket_count = 2;
134+ printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge.\n");
135+ printk(KERN_INFO "pd6729: configured as a %d socket device.\n", socket_count);
136+ /* Since we have no memory BARs some firmware we may not
137+ have had PCI_COMMAND_MEM enabled, yet the device needs
138+ it. */
139+ pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
140+ if (!(configbyte & PCI_COMMAND_MEMORY)) {
141+ printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
142+ configbyte |= PCI_COMMAND_MEMORY;
143+ pci_write_config_byte(dev, PCI_COMMAND, configbyte);
144+ }
145+
146+ if (pci_request_regions(dev, "pd6729")) {
147+ ret = -EBUSY;
148+ goto err_out_disable;
149+ }
150+
151+ for (i = 0;i<socket_count;i++) {
152+ sockets[i].card_state = 1; /* 1 = present but empty */
153+ sockets[i].io_base = pci_resource_start(dev, 0);
154+ sockets[i].socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
155+ sockets[i].socket.map_size = 0x1000;
156+ sockets[i].socket.irq_mask = 0;
157+ sockets[i].socket.pci_irq = dev->irq;
158+ sockets[i].socket.owner = THIS_MODULE;
159+
160+ sockets[i].number = i;
161+
162+ if (card_present(i)) {
163+ sockets[i].card_state = 3;
164+ dprintk(KERN_DEBUG "pd6729: slot %i is occupied\n",i);
165+ } else {
166+ dprintk(KERN_DEBUG "pd6729: slot %i is vacant\n",i);
167+ }
168+ }
169+
170+ /* Register the interrupt handler */
171+ dprintk(KERN_DEBUG "Requesting interrupt %i \n",dev->irq);
172+ if ((ret = request_irq(dev->irq, pd6729_interrupt, SA_SHIRQ, "pd6729", pd6729_interrupt))) {
173+ printk(KERN_ERR "pd6729: Failed to register IRQ %d, aborting\n", dev->irq);
174+ goto err_out_free_res;
175+ }
176+
177+ pci_set_drvdata(dev, &sockets[i].socket);
178+
179+ for (i = 0; i<socket_count; i++) {
180+ sockets[i].socket.dev.dev = &dev->dev;
181+ sockets[i].socket.ops = &pd6729_operations;
182+ ret = pcmcia_register_socket(&sockets[i].socket);
183+ if (ret) {
184+ goto err_out_free_sockets;
185+ }
186+ }
187+
188+ return 0;
189+
190+err_out_free_sockets:
191+ if (i) {
192+ for (i--;i>=0;i--) {
193+ pcmcia_unregister_socket(&sockets[i].socket);
194+ }
195+ }
196+ free_irq(dev->irq, pd6729_interrupt);
197+err_out_free_res:
198+ pci_release_regions(dev);
199+err_out_disable:
200+ pci_disable_device(dev);
201+ return ret;
202+}
203+
204+static void __devexit pd6729_pci_remove(struct pci_dev *dev)
205+{
206+ int i;
207+
208+ for (i = socket_count-1; i >=0 ; i--)
209+ pcmcia_unregister_socket(&sockets[i].socket);
210+
211+ free_irq(dev->irq, pd6729_interrupt);
212+ pci_release_regions(dev);
213+}
214+
215+static spinlock_t port_lock = SPIN_LOCK_UNLOCKED;
216+
217+/* basic value read/write functions */
218+
219+static unsigned char indirect_read(int socket, unsigned short reg)
220+{
221+ unsigned short int port;
222+ unsigned char val;
223+ unsigned long flags;
224+ spin_lock_irqsave(&port_lock,flags);
225+ reg += socket * 0x40;
226+ port = sockets[socket].io_base;
227+ outb(reg,port);
228+ val = inb(port+1);
229+ spin_unlock_irqrestore(&port_lock,flags);
230+ return val;
231+}
232+
233+static unsigned short indirect_read16(int socket, unsigned short reg)
234+{
235+ unsigned short int port;
236+ unsigned short tmp;
237+ unsigned long flags;
238+ spin_lock_irqsave(&port_lock,flags);
239+ reg = reg + socket * 0x40;
240+ port = sockets[socket].io_base;
241+ outb(reg,port);
242+ tmp = inb(port+1);
243+ reg++;
244+ outb(reg,port);
245+ tmp = tmp | (inb(port+1)<<8);
246+ spin_unlock_irqrestore(&port_lock,flags);
247+ return tmp;
248+}
249+
250+static void indirect_write(int socket, unsigned short reg, unsigned char value)
251+{
252+ unsigned short int port;
253+ unsigned long flags;
254+ spin_lock_irqsave(&port_lock,flags);
255+ reg = reg + socket * 0x40;
256+ port = sockets[socket].io_base;
257+ outb(reg,port);
258+ outb(value,port+1);
259+ spin_unlock_irqrestore(&port_lock,flags);
260+}
261+
262+static void indirect_setbit(int socket, unsigned short reg, unsigned char mask)
263+{
264+ unsigned short int port;
265+ unsigned char val;
266+ unsigned long flags;
267+ spin_lock_irqsave(&port_lock,flags);
268+ reg = reg + socket * 0x40;
269+ port = sockets[socket].io_base;
270+ outb(reg,port);
271+ val = inb(port+1);
272+ val |= mask;
273+ outb(reg,port);
274+ outb(val,port+1);
275+ spin_unlock_irqrestore(&port_lock,flags);
276+}
277+
278+static void indirect_resetbit(int socket, unsigned short reg, unsigned char mask)
279+{
280+ unsigned short int port;
281+ unsigned char val;
282+ unsigned long flags;
283+ spin_lock_irqsave(&port_lock,flags);
284+ reg = reg + socket * 0x40;
285+ port = sockets[socket].io_base;
286+ outb(reg,port);
287+ val = inb(port+1);
288+ val &= ~mask;
289+ outb(reg,port);
290+ outb(val,port+1);
291+ spin_unlock_irqrestore(&port_lock,flags);
292+}
293+
294+static void indirect_write16(int socket, unsigned short reg, unsigned short value)
295+{
296+ unsigned short int port;
297+ unsigned char val;
298+ unsigned long flags;
299+ spin_lock_irqsave(&port_lock,flags);
300+ reg = reg + socket * 0x40;
301+ port = sockets[socket].io_base;
302+
303+ outb(reg,port);
304+ val = value & 255;
305+ outb(val,port+1);
306+
307+ reg++;
308+
309+ outb(reg,port);
310+ val = value>>8;
311+ outb(val,port+1);
312+ spin_unlock_irqrestore(&port_lock,flags);
313+}
314+
315+/* simple helper functions */
316+/* External clock time, in nanoseconds. 120 ns = 8.33 MHz */
317+static int cycle_time = 120;
318+
319+static int to_cycles(int ns)
320+{
321+ if (cycle_time!=0)
322+ return ns/cycle_time;
323+ else
324+ return 0;
325+}
326+
327+/* Interrupt handler functionality */
328+
329+static irqreturn_t pd6729_interrupt(int irq, void *dev, struct pt_regs *regs)
330+{
331+ int i;
332+ int loopcount = 0;
333+ int handled = 0;
334+
335+ unsigned int events, active=0;
336+
337+ while (1) {
338+ loopcount++;
339+ if (loopcount>20) {
340+ printk(KERN_ERR "pd6729: infinite eventloop in interrupt \n");
341+ break;
342+ }
343+
344+ active = 0;
345+
346+ for (i=0;i<socket_count;i++) {
347+ int csc;
348+ if (sockets[i].card_state==0) /* Inactive socket, should not happen */
349+ continue;
350+
351+ csc = indirect_read(i,I365_CSC); /* card status change register */
352+
353+ if (csc==0) /* no events on this socket */
354+ continue;
355+ handled = 1;
356+ events = 0;
357+
358+ if (csc & I365_CSC_DETECT) {
359+ events |= SS_DETECT;
360+ dprintk("Card detected in socket %i!\n",i);
361+ }
362+
363+ if (indirect_read(i,I365_INTCTL) & I365_PC_IOCARD) {
364+ /* For IO/CARDS, bit 0 means "read the card" */
365+ events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
366+ } else {
367+ /* Check for battery/ready events */
368+ events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
369+ events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
370+ events |= (csc & I365_CSC_READY) ? SS_READY : 0;
371+ }
372+
373+ if (events) {
374+ pcmcia_parse_events(&sockets[i].socket, events);
375+ }
376+ active |= events;
377+ }
378+
379+ if (active==0) /* no more events to handle */
380+ break;
381+
382+ }
383+ return IRQ_RETVAL(handled);
384+}
385+
386+/* socket functions */
387+
388+static int card_present(int socketno)
389+{
390+ unsigned int val;
391+
392+ if ((socketno<0) || (socketno >= MAX_SOCKETS))
393+ return 0;
394+ if (sockets[socketno].io_base == 0)
395+ return 0;
396+
397+ val = indirect_read(socketno, 1); /* Interface status register */
398+ if ((val&12)==12) {
399+ dprintk("card_present 1");
400+ return 1;
401+ }
402+
403+ dprintk("card_present 0");
404+ return 0;
405+}
406+
407+static void set_bridge_state(int sock)
408+{
409+ indirect_write(sock, I365_GBLCTL,0x00);
410+ indirect_write(sock, I365_GENCTL,0x00);
411+
412+ indirect_setbit(sock, I365_INTCTL,0x08);
413+}
414+
415+static int pd6729_init(struct pcmcia_socket *sock)
416+{
417+ int i;
418+ pccard_io_map io = { 0, 0, 0, 0, 1 };
419+ pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
420+
421+ mem.sys_stop = 0x0fff;
422+ pd6729_set_socket(sock, &dead_socket);
423+ for (i = 0; i < 2; i++) {
424+ io.map = i;
425+ pd6729_set_io_map(sock, &io);
426+ }
427+ for (i = 0; i < 5; i++) {
428+ mem.map = i;
429+ pd6729_set_mem_map(sock, &mem);
430+ }
431+
432+ return 0;
433+}
434+
435+static int pd6729_suspend(struct pcmcia_socket *sock)
436+{
437+ int retval;
438+ retval = pd6729_set_socket(sock, &dead_socket);
439+ return retval;
440+}
441+
442+static int pd6729_get_status(struct pcmcia_socket *socket, u_int *value)
443+{
444+ unsigned int sock = container_of(socket, struct socket_info, socket)->number;
445+ unsigned int status;
446+ unsigned int data, t;
447+
448+ status = indirect_read(sock,I365_STATUS); /* Interface Status Register */
449+ *value = 0;
450+
451+ if ((status & I365_CS_DETECT) == I365_CS_DETECT) {
452+ *value |= SS_DETECT;
453+ }
454+
455+ /* IO cards have a different meaning of bits 0,1 */
456+ /* Also notice the inverse-logic on the bits */
457+ if (indirect_read(sock, I365_INTCTL) & I365_PC_IOCARD) {
458+ /* IO card */
459+ if (!(status & I365_CS_STSCHG))
460+ *value |= SS_STSCHG;
461+ } else { /* non I/O card */
462+ if (!(status & I365_CS_BVD1))
463+ *value |= SS_BATDEAD;
464+ if (!(status & I365_CS_BVD2))
465+ *value |= SS_BATWARN;
466+
467+ }
468+
469+ if (status & I365_CS_WRPROT)
470+ (*value) |= SS_WRPROT; /* card is write protected */
471+
472+ if (status & I365_CS_READY)
473+ (*value) |= SS_READY; /* card is not busy */
474+
475+ if (status & I365_CS_POWERON)
476+ (*value) |= SS_POWERON; /* power is applied to the card */
477+
478+ t = (sock) ? sock : sock+1;
479+ indirect_write(t, PD67_EXT_INDEX, PD67_EXTERN_DATA);
480+ data = indirect_read16(t, PD67_EXT_DATA);
481+ *value |= (data & PD67_EXD_VS1(sock)) ? 0 : SS_3VCARD; /* 3.3V card */
482+
483+ return 0;
484+}
485+
486+
487+static int pd6729_get_socket(struct pcmcia_socket *socket, socket_state_t *state)
488+{
489+ unsigned int sock = container_of(socket, struct socket_info, socket)->number;
490+ unsigned char reg,vcc,vpp;
491+
492+ state->flags = 0;
493+ state->Vcc = 0;
494+ state->Vpp = 0;
495+ state->io_irq = 0;
496+ state->csc_mask = 0;
497+
498+ /* First the power status of the socket */
499+ reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */
500+
501+ if (reg & I365_PWR_AUTO)
502+ state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */
503+
504+ if (reg & I365_PWR_OUT)
505+ state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
506+
507+ vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
508+
509+ if (reg & I365_VCC_5V) {
510+ state->Vcc = (indirect_read(sock, PD67_MISC_CTL_1) &
511+ PD67_MC1_VCC_3V) ? 33 : 50;
512+
513+ if (vpp == I365_VPP1_5V) {
514+ if (state->Vcc == 50) state->Vpp = 50;
515+ else state->Vpp = 33;
516+ }
517+ if (vpp == I365_VPP1_12V)
518+ state->Vpp = 120;
519+
520+ }
521+
522+ /* Now the IO card, RESET flags and IO interrupt */
523+
524+ reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */
525+
526+ if ((reg & I365_PC_RESET)==0)
527+ state->flags |= SS_RESET;
528+ if (reg & I365_PC_IOCARD)
529+ state->flags |= SS_IOCARD; /* This is an IO card */
530+
531+ /* Set the IRQ number */
532+ if (sockets[sock].dev!=NULL)
533+ state->io_irq = sockets[sock].dev->irq;
534+
535+ /* Card status change */
536+ reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */
537+
538+ if (reg & I365_CSC_DETECT)
539+ state->csc_mask |= SS_DETECT; /* Card detect is enabled */
540+
541+ if (state->flags & SS_IOCARD) {/* IO Cards behave different */
542+ if (reg & I365_CSC_STSCHG)
543+ state->csc_mask |= SS_STSCHG;
544+ } else {
545+ if (reg & I365_CSC_BVD1)
546+ state->csc_mask |= SS_BATDEAD;
547+ if (reg & I365_CSC_BVD2)
548+ state->csc_mask |= SS_BATWARN;
549+ if (reg & I365_CSC_READY)
550+ state->csc_mask |= SS_READY;
551+ }
552+
553+ return 0;
554+}
555+
556+static int pd6729_set_socket(struct pcmcia_socket *socket, socket_state_t *state)
557+{
558+ unsigned int sock = container_of(socket, struct socket_info, socket)->number;
559+ unsigned char reg;
560+
561+ /* First, set the global controller options */
562+
563+ set_bridge_state(sock);
564+
565+ /* Values for the IGENC register */
566+
567+ reg = 0;
568+ if (!(state->flags & SS_RESET)) /* The reset bit has "inverse" logic */
569+ reg = reg | I365_PC_RESET;
570+ if (state->flags & SS_IOCARD)
571+ reg = reg | I365_PC_IOCARD;
572+
573+ indirect_write(sock,I365_INTCTL,reg); /* IGENC, Interrupt and General Control Register */
574+
575+ /* Power registers */
576+
577+ reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
578+
579+ if (state->flags & SS_PWR_AUTO) {
580+ dprintk("Auto power\n");
581+ reg |= I365_PWR_AUTO; /* automatic power mngmnt */
582+ }
583+ if (state->flags & SS_OUTPUT_ENA) {
584+ dprintk("Power Enabled \n");
585+ reg |= I365_PWR_OUT; /* enable power */
586+ }
587+
588+ switch (state->Vcc) {
589+ case 0:
590+ break;
591+ case 33:
592+ dprintk("setting voltage to Vcc to 3.3V on socket %i\n",sock);
593+ reg |= I365_VCC_5V;
594+ indirect_setbit(sock,PD67_MISC_CTL_1,PD67_MC1_VCC_3V);
595+ break;
596+ case 50:
597+ dprintk("setting voltage to Vcc to 5V on socket %i\n",sock);
598+ reg |= I365_VCC_5V;
599+ indirect_resetbit(sock,PD67_MISC_CTL_1,PD67_MC1_VCC_3V);
600+ break;
601+ default:
602+ dprintk("pd6729: pd6729_set_socket called with invalid VCC power value: %i ", state->Vcc);
603+ return -EINVAL;
604+ }
605+
606+ switch (state->Vpp) {
607+ case 0:
608+ dprintk("not setting Vpp on socket %i\n",sock);
609+ break;
610+ case 33:
611+ case 50:
612+ dprintk("setting Vpp to Vcc for socket %i\n",sock);
613+ reg |= I365_VPP1_5V;
614+ break;
615+ case 120:
616+ dprintk("setting Vpp to 12.0\n");
617+ reg |= I365_VPP1_12V;
618+ break;
619+ default:
620+ dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i ", state->Vpp);
621+ return -EINVAL;
622+ }
623+
624+ if (reg != indirect_read(sock,I365_POWER)) /* only write if changed */
625+ indirect_write(sock,I365_POWER,reg);
626+
627+ /* Now, specifiy that all interrupts are to be done as PCI interrupts */
628+ indirect_write(sock, PD67_EXT_INDEX, PD67_EXT_CTL_1);
629+ indirect_write(sock, PD67_EXT_DATA, PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ);
630+
631+ /* Enable specific interrupt events */
632+
633+ reg = 0x00;
634+ if (state->csc_mask & SS_DETECT) {
635+ reg |= I365_CSC_DETECT;
636+ }
637+ if (state->flags & SS_IOCARD) {
638+ if (state->csc_mask & SS_STSCHG)
639+ reg |= I365_CSC_STSCHG;
640+ } else {
641+ if (state->csc_mask & SS_BATDEAD)
642+ reg |= I365_CSC_BVD1;
643+ if (state->csc_mask & SS_BATWARN)
644+ reg |= I365_CSC_BVD2;
645+ if (state->csc_mask & SS_READY)
646+ reg |= I365_CSC_READY;
647+ }
648+ reg |= 0x30; /* management IRQ: PCI INTA# = "irq 3" */
649+ indirect_write(sock,I365_CSCINT,reg);
650+
651+ reg = indirect_read(sock,I365_INTCTL);
652+ reg |= 0x03; /* card IRQ: PCI INTA# = "irq 3" */
653+ indirect_write(sock,I365_INTCTL,reg);
654+
655+ /* now clear the (probably bogus) pending stuff by doing a dummy read*/
656+ (void)indirect_read(sock,I365_CSC);
657+
658+ return 0;
659+}
660+
661+static int pd6729_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io)
662+{
663+ unsigned int sock = container_of(socket, struct socket_info, socket)->number;
664+ unsigned char map, ioctl;
665+
666+ map = io->map;
667+
668+ /* Check error conditions */
669+ if (map > 1) {
670+ dprintk("pd6729_set_io_map with invalid map");
671+ return -EINVAL;
672+ }
673+ if ((io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)){
674+ dprintk("pd6729_set_io_map with invalid io");
675+ return -EINVAL;
676+ }
677+
678+ /* Turn off the window before changing anything */
679+ if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_IO(map))
680+ indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
681+
682+/* printk("set_io_map: Setting range to %x - %x \n",io->start,io->stop); */
683+
684+ /* write the new values */
685+ indirect_write16(sock,I365_IO(map)+I365_W_START,io->start);
686+ indirect_write16(sock,I365_IO(map)+I365_W_STOP,io->stop);
687+
688+ ioctl = indirect_read(sock,I365_IOCTL) & ~I365_IOCTL_MASK(map);
689+
690+ if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
691+ if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
692+ if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
693+
694+ indirect_write(sock,I365_IOCTL,ioctl);
695+
696+ /* Turn the window back on if needed */
697+ if (io->flags & MAP_ACTIVE)
698+ indirect_setbit(sock,I365_ADDRWIN,I365_ENA_IO(map));
699+
700+ return 0;
701+}
702+
703+static int pd6729_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem)
704+{
705+ unsigned int sock = container_of(socket, struct socket_info, socket)->number;
706+ unsigned short base, i;
707+ unsigned char map;
708+
709+ map = mem->map;
710+ if (map > 4) {
711+ printk("pd6729_set_mem_map: invalid map");
712+ return -EINVAL;
713+ }
714+
715+ if ( (mem->sys_start > mem->sys_stop) || (mem->speed > 1000) ) {
716+ printk("pd6729_set_mem_map: invalid address / speed");
717+ printk("invalid mem map for socket %i : %lx to %lx with a start of %x \n",sock,mem->sys_start, mem->sys_stop, mem->card_start);
718+ return -EINVAL;
719+ }
720+
721+ /* Turn off the window before changing anything */
722+ if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
723+ indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
724+
725+/* printk("set_mem_map: Setting map %i range to %x - %x on socket %i, speed is %i, active = %i \n",map, mem->sys_start,mem->sys_stop,sock,mem->speed,mem->flags & MAP_ACTIVE); */
726+
727+ /* write the start address */
728+ base = I365_MEM(map);
729+ i = (mem->sys_start >> 12) & 0x0fff;
730+ if (mem->flags & MAP_16BIT)
731+ i |= I365_MEM_16BIT;
732+ if (mem->flags & MAP_0WS)
733+ i |= I365_MEM_0WS;
734+ indirect_write16(sock,base+I365_W_START,i);
735+
736+ /* write the stop address */
737+
738+ i= (mem->sys_stop >> 12) & 0x0fff;
739+ switch (to_cycles(mem->speed)) {
740+ case 0:
741+ break;
742+ case 1:
743+ i |= I365_MEM_WS0;
744+ break;
745+ case 2:
746+ i |= I365_MEM_WS1;
747+ break;
748+ default:
749+ i |= I365_MEM_WS1 | I365_MEM_WS0;
750+ break;
751+ }
752+
753+ indirect_write16(sock,base+I365_W_STOP,i);
754+
755+ /* Take care of high byte */
756+ indirect_write(sock, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
757+ indirect_write(sock, PD67_EXT_DATA, mem->sys_start >> 24);
758+
759+ /* card start */
760+
761+ i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
762+ if (mem->flags & MAP_WRPROT)
763+ i |= I365_MEM_WRPROT;
764+ if (mem->flags & MAP_ATTRIB) {
765+/* printk("requesting attribute memory for socket %i\n",sock);*/
766+ i |= I365_MEM_REG;
767+ } else {
768+/* printk("requesting normal memory for socket %i\n",sock);*/
769+ }
770+ indirect_write16(sock,base+I365_W_OFF,i);
771+
772+ /* Enable the window if necessary */
773+ if (mem->flags & MAP_ACTIVE)
774+ indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
775+
776+ return 0;
777+}
778+
779+static int pd6729_module_init(void)
780+{
781+ return pci_module_init (&pd6729_pci_drv);
782+}
783+
784+static void pd6729_module_exit(void)
785+{
786+ pci_unregister_driver(&pd6729_pci_drv);
787+}
788+
789+module_init(pd6729_module_init);
790+module_exit(pd6729_module_exit);
791+
792diff -ruN linux/drivers/pcmcia.orig/pd6729.h linux/drivers/pcmcia/pd6729.h
793--- linux/drivers/pcmcia.orig/pd6729.h 1970-01-01 09:00:00.000000000 +0900
794+++ linux/drivers/pcmcia/pd6729.h 2004-01-13 21:28:09.000000000 +0900
795@@ -0,0 +1,42 @@
796+#ifndef _INCLUDE_GUARD_PD6729_H_
797+#define _INCLUDE_GUARD_PD6729_H_
798+
799+#include <linux/interrupt.h>
800+
801+
802+/* Debuging defines */
803+#ifdef NOTRACE
804+#define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
805+#define leave(x) printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__)
806+#define dprintk(fmt, args...) printk(fmt , ## args)
807+#else
808+#define enter(x) do {} while (0)
809+#define leave(x) do {} while (0)
810+#define dprintk(fmt, args...) do {} while (0)
811+#endif
812+
813+
814+/* Flags for I365_GENCTL */
815+#define I365_DF_VS1 0x40 /* DF-step Voltage Sense */
816+#define I365_DF_VS2 0x80
817+
818+/* Fields in PD67_EXTERN_DATA */
819+#define PD67_EXD_VS1(s) (0x01 << ((s)<<1))
820+#define PD67_EXD_VS2(s) (0x02 << ((s)<<1))
821+
822+/* prototypes */
823+
824+static int pd6729_pci_probe(struct pci_dev *dev, const struct pci_device_id *id);
825+static void pd6729_pci_remove(struct pci_dev *dev);
826+static int card_present(int socketno);
827+static irqreturn_t pd6729_interrupt(int irq, void *dev, struct pt_regs *regs);
828+static int pd6729_get_status(struct pcmcia_socket *socket, u_int *value);
829+static int pd6729_get_socket(struct pcmcia_socket *socket, socket_state_t *state);
830+static int pd6729_set_socket(struct pcmcia_socket *socket, socket_state_t *state);
831+static int pd6729_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io);
832+static int pd6729_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem);
833+static int pd6729_init(struct pcmcia_socket *socket);
834+static int pd6729_suspend(struct pcmcia_socket *socket);
835+
836+#endif
837+
This page took 0.202623 seconds and 4 git commands to generate.