mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-15 13:57:43 +07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (50 commits) pcmcia: rework the irq_req_t typedef pcmcia: remove deprecated handle_to_dev() macro pcmcia: pcmcia_request_window() doesn't need a pointer to a pointer pcmcia: remove unused "window_t" typedef pcmcia: move some window-related code to pcmcia_ioctl.c pcmcia: Change window_handle_t logic to unsigned long pcmcia: Pass struct pcmcia_socket to pcmcia_get_mem_page() pcmcia: Pass struct pcmcia_device to pcmcia_map_mem_page() pcmcia: Pass struct pcmcia_device to pcmcia_release_window() drivers/pcmcia: remove unnecessary kzalloc pcmcia: correct handling for Zoomed Video registers in topic.h pcmcia: fix printk formats pcmcia: autoload module pcmcia pcmcia/staging: update comedi drivers PCMCIA: stop duplicating pci_irq in soc_pcmcia_socket PCMCIA: ss: allow PCI IRQs > 255 PCMCIA: soc_common: remove 'dev' member from soc_pcmcia_socket PCMCIA: soc_common: constify soc_pcmcia_socket ops member PCMCIA: sa1111: remove duplicated initializers PCMCIA: sa1111: wrap soc_pcmcia_socket to contain sa1111 specific data ...
This commit is contained in:
commit
d9b2c4d0b0
@ -1,5 +1,17 @@
|
|||||||
This file details changes in 2.6 which affect PCMCIA card driver authors:
|
This file details changes in 2.6 which affect PCMCIA card driver authors:
|
||||||
|
|
||||||
|
* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
|
||||||
|
Instead of the cs_error() callback or the CS_CHECK() macro, please use
|
||||||
|
Linux-style checking of return values, and -- if necessary -- debug
|
||||||
|
messages using "dev_dbg()" or "pr_debug()".
|
||||||
|
|
||||||
|
* New CIS tuple access (as of 2.6.33)
|
||||||
|
Instead of pcmcia_get_{first,next}_tuple(), pcmcia_get_tuple_data() and
|
||||||
|
pcmcia_parse_tuple(), a driver shall use "pcmcia_get_tuple()" if it is
|
||||||
|
only interested in one (raw) tuple, or "pcmcia_loop_tuple()" if it is
|
||||||
|
interested in all tuples of one type. To decode the MAC from CISTPL_FUNCE,
|
||||||
|
a new helper "pcmcia_get_mac_from_cis()" was added.
|
||||||
|
|
||||||
* New configuration loop helper (as of 2.6.28)
|
* New configuration loop helper (as of 2.6.28)
|
||||||
By calling pcmcia_loop_config(), a driver can iterate over all available
|
By calling pcmcia_loop_config(), a driver can iterate over all available
|
||||||
configuration options. During a driver's probe() phase, one doesn't need
|
configuration options. During a driver's probe() phase, one doesn't need
|
||||||
|
@ -177,9 +177,6 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
|
|||||||
.drain_fifo = pcmcia_8bit_drain_fifo,
|
.drain_fifo = pcmcia_8bit_drain_fifo,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
|
|
||||||
struct pcmcia_config_check {
|
struct pcmcia_config_check {
|
||||||
unsigned long ctl_base;
|
unsigned long ctl_base;
|
||||||
@ -252,7 +249,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||||||
struct ata_port *ap;
|
struct ata_port *ap;
|
||||||
struct ata_pcmcia_info *info;
|
struct ata_pcmcia_info *info;
|
||||||
struct pcmcia_config_check *stk = NULL;
|
struct pcmcia_config_check *stk = NULL;
|
||||||
int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
|
int is_kme = 0, ret = -ENOMEM, p;
|
||||||
unsigned long io_base, ctl_base;
|
unsigned long io_base, ctl_base;
|
||||||
void __iomem *io_addr, *ctl_addr;
|
void __iomem *io_addr, *ctl_addr;
|
||||||
int n_ports = 1;
|
int n_ports = 1;
|
||||||
@ -271,7 +268,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||||||
pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||||
pdev->io.IOAddrLines = 3;
|
pdev->io.IOAddrLines = 3;
|
||||||
pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
pdev->conf.Attributes = CONF_ENABLE_IRQ;
|
pdev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
pdev->conf.IntType = INT_MEMORY_AND_IO;
|
pdev->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -296,8 +292,13 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||||||
}
|
}
|
||||||
io_base = pdev->io.BasePort1;
|
io_base = pdev->io.BasePort1;
|
||||||
ctl_base = stk->ctl_base;
|
ctl_base = stk->ctl_base;
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
|
ret = pcmcia_request_irq(pdev, &pdev->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
ret = pcmcia_request_configuration(pdev, &pdev->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* iomap */
|
/* iomap */
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
@ -351,8 +352,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||||||
kfree(stk);
|
kfree(stk);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(pdev, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
kfree(stk);
|
kfree(stk);
|
||||||
info->ndev = 0;
|
info->ndev = 0;
|
||||||
|
@ -867,11 +867,9 @@ static int bluecard_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts1 = 8;
|
link->io.NumPorts1 = 8;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
link->irq.Handler = bluecard_interrupt;
|
link->irq.Handler = bluecard_interrupt;
|
||||||
link->irq.Instance = info;
|
|
||||||
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
@ -905,22 +903,16 @@ static int bluecard_config(struct pcmcia_device *link)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIO, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
}
|
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
if (bluecard_open(info) != 0)
|
if (bluecard_open(info) != 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -659,11 +659,9 @@ static int bt3c_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts1 = 8;
|
link->io.NumPorts1 = 8;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
link->irq.Handler = bt3c_interrupt;
|
link->irq.Handler = bt3c_interrupt;
|
||||||
link->irq.Instance = info;
|
|
||||||
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
@ -740,21 +738,16 @@ static int bt3c_config(struct pcmcia_device *link)
|
|||||||
goto found_port;
|
goto found_port;
|
||||||
|
|
||||||
BT_ERR("No usable port range found");
|
BT_ERR("No usable port range found");
|
||||||
cs_error(link, RequestIO, -ENODEV);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
found_port:
|
found_port:
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
}
|
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
if (bt3c_open(info) != 0)
|
if (bt3c_open(info) != 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -588,11 +588,9 @@ static int btuart_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts1 = 8;
|
link->io.NumPorts1 = 8;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
link->irq.Handler = btuart_interrupt;
|
link->irq.Handler = btuart_interrupt;
|
||||||
link->irq.Instance = info;
|
|
||||||
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
@ -669,21 +667,16 @@ static int btuart_config(struct pcmcia_device *link)
|
|||||||
goto found_port;
|
goto found_port;
|
||||||
|
|
||||||
BT_ERR("No usable port range found");
|
BT_ERR("No usable port range found");
|
||||||
cs_error(link, RequestIO, -ENODEV);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
found_port:
|
found_port:
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
}
|
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
if (btuart_open(info) != 0)
|
if (btuart_open(info) != 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -573,11 +573,9 @@ static int dtl1_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts1 = 8;
|
link->io.NumPorts1 = 8;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
link->irq.Handler = dtl1_interrupt;
|
link->irq.Handler = dtl1_interrupt;
|
||||||
link->irq.Instance = info;
|
|
||||||
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
@ -622,16 +620,12 @@ static int dtl1_config(struct pcmcia_device *link)
|
|||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
}
|
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
if (dtl1_open(info) != 0)
|
if (dtl1_open(info) != 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
* All rights reserved. Licensed under dual BSD/GPL license.
|
* All rights reserved. Licensed under dual BSD/GPL license.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* #define PCMCIA_DEBUG 6 */
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
@ -47,18 +45,17 @@
|
|||||||
|
|
||||||
/* #define ATR_CSUM */
|
/* #define ATR_CSUM */
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#define reader_to_dev(x) (&x->p_dev->dev)
|
||||||
#define reader_to_dev(x) (&handle_to_dev(x->p_dev))
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
/* n (debug level) is ignored */
|
||||||
module_param(pc_debug, int, 0600);
|
/* additional debug output may be enabled by re-compiling with
|
||||||
#define DEBUGP(n, rdr, x, args...) do { \
|
* CM4000_DEBUG set */
|
||||||
if (pc_debug >= (n)) \
|
/* #define CM4000_DEBUG */
|
||||||
dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
|
#define DEBUGP(n, rdr, x, args...) do { \
|
||||||
__func__ , ## args); \
|
dev_dbg(reader_to_dev(rdr), "%s:" x, \
|
||||||
|
__func__ , ## args); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
|
||||||
#define DEBUGP(n, rdr, x, args...)
|
|
||||||
#endif
|
|
||||||
static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
|
static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
|
||||||
|
|
||||||
#define T_1SEC (HZ)
|
#define T_1SEC (HZ)
|
||||||
@ -174,14 +171,13 @@ static unsigned char fi_di_table[10][14] = {
|
|||||||
/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
|
/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef PCMCIA_DEBUG
|
#ifndef CM4000_DEBUG
|
||||||
#define xoutb outb
|
#define xoutb outb
|
||||||
#define xinb inb
|
#define xinb inb
|
||||||
#else
|
#else
|
||||||
static inline void xoutb(unsigned char val, unsigned short port)
|
static inline void xoutb(unsigned char val, unsigned short port)
|
||||||
{
|
{
|
||||||
if (pc_debug >= 7)
|
pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
|
||||||
printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
|
|
||||||
outb(val, port);
|
outb(val, port);
|
||||||
}
|
}
|
||||||
static inline unsigned char xinb(unsigned short port)
|
static inline unsigned char xinb(unsigned short port)
|
||||||
@ -189,8 +185,7 @@ static inline unsigned char xinb(unsigned short port)
|
|||||||
unsigned char val;
|
unsigned char val;
|
||||||
|
|
||||||
val = inb(port);
|
val = inb(port);
|
||||||
if (pc_debug >= 7)
|
pr_debug("%.2x=inb(%.4x)\n", val, port);
|
||||||
printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
|
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -514,12 +509,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
|
|||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
xoutb(i, REG_BUF_ADDR(iobase));
|
xoutb(i, REG_BUF_ADDR(iobase));
|
||||||
xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */
|
xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4000_DEBUG
|
||||||
if (pc_debug >= 5)
|
pr_debug("0x%.2x ", dev->pts[i]);
|
||||||
printk("0x%.2x ", dev->pts[i]);
|
|
||||||
}
|
}
|
||||||
if (pc_debug >= 5)
|
pr_debug("\n");
|
||||||
printk("\n");
|
|
||||||
#else
|
#else
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -579,14 +572,13 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
|
|||||||
pts_reply[i] = inb(REG_BUF_DATA(iobase));
|
pts_reply[i] = inb(REG_BUF_DATA(iobase));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4000_DEBUG
|
||||||
DEBUGP(2, dev, "PTSreply: ");
|
DEBUGP(2, dev, "PTSreply: ");
|
||||||
for (i = 0; i < num_bytes_read; i++) {
|
for (i = 0; i < num_bytes_read; i++) {
|
||||||
if (pc_debug >= 5)
|
pr_debug("0x%.2x ", pts_reply[i]);
|
||||||
printk("0x%.2x ", pts_reply[i]);
|
|
||||||
}
|
}
|
||||||
printk("\n");
|
pr_debug("\n");
|
||||||
#endif /* PCMCIA_DEBUG */
|
#endif /* CM4000_DEBUG */
|
||||||
|
|
||||||
DEBUGP(5, dev, "Clear Tactive in Flags1\n");
|
DEBUGP(5, dev, "Clear Tactive in Flags1\n");
|
||||||
xoutb(0x20, REG_FLAGS1(iobase));
|
xoutb(0x20, REG_FLAGS1(iobase));
|
||||||
@ -655,7 +647,7 @@ static void terminate_monitor(struct cm4000_dev *dev)
|
|||||||
|
|
||||||
DEBUGP(5, dev, "Delete timer\n");
|
DEBUGP(5, dev, "Delete timer\n");
|
||||||
del_timer_sync(&dev->timer);
|
del_timer_sync(&dev->timer);
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4000_DEBUG
|
||||||
dev->monitor_running = 0;
|
dev->monitor_running = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -898,7 +890,7 @@ static void monitor_card(unsigned long p)
|
|||||||
DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
|
DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
|
||||||
"be zero) failed\n", dev->atr_csum);
|
"be zero) failed\n", dev->atr_csum);
|
||||||
}
|
}
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4000_DEBUG
|
||||||
else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
|
else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
|
||||||
DEBUGP(4, dev, "ATR length error\n");
|
DEBUGP(4, dev, "ATR length error\n");
|
||||||
} else {
|
} else {
|
||||||
@ -1415,7 +1407,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||||||
int size;
|
int size;
|
||||||
int rc;
|
int rc;
|
||||||
void __user *argp = (void __user *)arg;
|
void __user *argp = (void __user *)arg;
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4000_DEBUG
|
||||||
char *ioctl_names[CM_IOC_MAXNR + 1] = {
|
char *ioctl_names[CM_IOC_MAXNR + 1] = {
|
||||||
[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
|
[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
|
||||||
[_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
|
[_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
|
||||||
@ -1423,9 +1415,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||||||
[_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
|
[_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
|
||||||
[_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
|
[_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
|
DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
|
||||||
iminor(inode), ioctl_names[_IOC_NR(cmd)]);
|
iminor(inode), ioctl_names[_IOC_NR(cmd)]);
|
||||||
|
#endif
|
||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
@ -1523,7 +1515,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||||||
}
|
}
|
||||||
case CM_IOCARDOFF:
|
case CM_IOCARDOFF:
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4000_DEBUG
|
||||||
DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
|
DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
|
||||||
if (dev->flags0 & 0x01) {
|
if (dev->flags0 & 0x01) {
|
||||||
DEBUGP(4, dev, " Card inserted\n");
|
DEBUGP(4, dev, " Card inserted\n");
|
||||||
@ -1625,18 +1617,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4000_DEBUG
|
||||||
case CM_IOSDBGLVL: /* set debug log level */
|
case CM_IOSDBGLVL:
|
||||||
{
|
rc = -ENOTTY;
|
||||||
int old_pc_debug = 0;
|
|
||||||
|
|
||||||
old_pc_debug = pc_debug;
|
|
||||||
if (copy_from_user(&pc_debug, argp, sizeof(int)))
|
|
||||||
rc = -EFAULT;
|
|
||||||
else if (old_pc_debug != pc_debug)
|
|
||||||
DEBUGP(0, dev, "Changed debug log level "
|
|
||||||
"to %i\n", pc_debug);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
* All rights reserved, Dual BSD/GPL Licensed.
|
* All rights reserved, Dual BSD/GPL Licensed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* #define PCMCIA_DEBUG 6 */
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
@ -41,18 +39,16 @@
|
|||||||
#include "cm4040_cs.h"
|
#include "cm4040_cs.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#define reader_to_dev(x) (&x->p_dev->dev)
|
||||||
#define reader_to_dev(x) (&handle_to_dev(x->p_dev))
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
/* n (debug level) is ignored */
|
||||||
module_param(pc_debug, int, 0600);
|
/* additional debug output may be enabled by re-compiling with
|
||||||
#define DEBUGP(n, rdr, x, args...) do { \
|
* CM4040_DEBUG set */
|
||||||
if (pc_debug >= (n)) \
|
/* #define CM4040_DEBUG */
|
||||||
dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
|
#define DEBUGP(n, rdr, x, args...) do { \
|
||||||
__func__ , ##args); \
|
dev_dbg(reader_to_dev(rdr), "%s:" x, \
|
||||||
|
__func__ , ## args); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
|
||||||
#define DEBUGP(n, rdr, x, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char *version =
|
static char *version =
|
||||||
"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
|
"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
|
||||||
@ -90,14 +86,13 @@ struct reader_dev {
|
|||||||
|
|
||||||
static struct pcmcia_device *dev_table[CM_MAX_DEV];
|
static struct pcmcia_device *dev_table[CM_MAX_DEV];
|
||||||
|
|
||||||
#ifndef PCMCIA_DEBUG
|
#ifndef CM4040_DEBUG
|
||||||
#define xoutb outb
|
#define xoutb outb
|
||||||
#define xinb inb
|
#define xinb inb
|
||||||
#else
|
#else
|
||||||
static inline void xoutb(unsigned char val, unsigned short port)
|
static inline void xoutb(unsigned char val, unsigned short port)
|
||||||
{
|
{
|
||||||
if (pc_debug >= 7)
|
pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
|
||||||
printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
|
|
||||||
outb(val, port);
|
outb(val, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +101,7 @@ static inline unsigned char xinb(unsigned short port)
|
|||||||
unsigned char val;
|
unsigned char val;
|
||||||
|
|
||||||
val = inb(port);
|
val = inb(port);
|
||||||
if (pc_debug >= 7)
|
pr_debug("%.2x=inb(%.4x)\n", val, port);
|
||||||
printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -260,23 +254,22 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
|
dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4040_DEBUG
|
||||||
if (pc_debug >= 6)
|
pr_debug("%lu:%2x ", i, dev->r_buf[i]);
|
||||||
printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
|
|
||||||
}
|
}
|
||||||
printk("\n");
|
pr_debug("\n");
|
||||||
#else
|
#else
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
|
bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
|
||||||
|
|
||||||
DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
|
DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read);
|
||||||
|
|
||||||
min_bytes_to_read = min(count, bytes_to_read + 5);
|
min_bytes_to_read = min(count, bytes_to_read + 5);
|
||||||
min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE);
|
min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE);
|
||||||
|
|
||||||
DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
|
DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read);
|
||||||
|
|
||||||
for (i = 0; i < (min_bytes_to_read-5); i++) {
|
for (i = 0; i < (min_bytes_to_read-5); i++) {
|
||||||
rc = wait_for_bulk_in_ready(dev);
|
rc = wait_for_bulk_in_ready(dev);
|
||||||
@ -288,11 +281,10 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
|
dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef CM4040_DEBUG
|
||||||
if (pc_debug >= 6)
|
pr_debug("%lu:%2x ", i, dev->r_buf[i]);
|
||||||
printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
|
|
||||||
}
|
}
|
||||||
printk("\n");
|
pr_debug("\n");
|
||||||
#else
|
#else
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -547,7 +539,7 @@ static int cm4040_config_check(struct pcmcia_device *p_dev,
|
|||||||
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
|
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
|
||||||
|
|
||||||
rc = pcmcia_request_io(p_dev, &p_dev->io);
|
rc = pcmcia_request_io(p_dev, &p_dev->io);
|
||||||
dev_printk(KERN_INFO, &handle_to_dev(p_dev),
|
dev_printk(KERN_INFO, &p_dev->dev,
|
||||||
"pcmcia_request_io returned 0x%x\n", rc);
|
"pcmcia_request_io returned 0x%x\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -569,7 +561,7 @@ static int reader_config(struct pcmcia_device *link, int devno)
|
|||||||
|
|
||||||
fail_rc = pcmcia_request_configuration(link, &link->conf);
|
fail_rc = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (fail_rc != 0) {
|
if (fail_rc != 0) {
|
||||||
dev_printk(KERN_INFO, &handle_to_dev(link),
|
dev_printk(KERN_INFO, &link->dev,
|
||||||
"pcmcia_request_configuration failed 0x%x\n",
|
"pcmcia_request_configuration failed 0x%x\n",
|
||||||
fail_rc);
|
fail_rc);
|
||||||
goto cs_release;
|
goto cs_release;
|
||||||
|
@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
|
|||||||
|
|
||||||
irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
|
irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct ipw_hardware *hw = dev_id;
|
struct ipw_dev *ipw = dev_id;
|
||||||
|
|
||||||
if (hw->hw_version == HW_VERSION_1)
|
if (ipw->hardware->hw_version == HW_VERSION_1)
|
||||||
return ipwireless_handle_v1_interrupt(irq, hw);
|
return ipwireless_handle_v1_interrupt(irq, ipw->hardware);
|
||||||
else
|
else
|
||||||
return ipwireless_handle_v2_v3_interrupt(irq, hw);
|
return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_packets_to_hw(struct ipw_hardware *hw)
|
static void flush_packets_to_hw(struct ipw_hardware *hw)
|
||||||
|
@ -65,10 +65,7 @@ static void signalled_reboot_work(struct work_struct *work_reboot)
|
|||||||
struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
|
struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
|
||||||
work_reboot);
|
work_reboot);
|
||||||
struct pcmcia_device *link = ipw->link;
|
struct pcmcia_device *link = ipw->link;
|
||||||
int ret = pcmcia_reset_card(link->socket);
|
pcmcia_reset_card(link->socket);
|
||||||
|
|
||||||
if (ret != 0)
|
|
||||||
cs_error(link, ResetCard, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void signalled_reboot_callback(void *callback_data)
|
static void signalled_reboot_callback(void *callback_data)
|
||||||
@ -79,208 +76,127 @@ static void signalled_reboot_callback(void *callback_data)
|
|||||||
schedule_work(&ipw->work_reboot);
|
schedule_work(&ipw->work_reboot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int config_ipwireless(struct ipw_dev *ipw)
|
static int ipwireless_probe(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
{
|
{
|
||||||
struct pcmcia_device *link = ipw->link;
|
struct ipw_dev *ipw = priv_data;
|
||||||
int ret;
|
struct resource *io_resource;
|
||||||
tuple_t tuple;
|
|
||||||
unsigned short buf[64];
|
|
||||||
cisparse_t parse;
|
|
||||||
unsigned short cor_value;
|
|
||||||
memreq_t memreq_attr_memory;
|
memreq_t memreq_attr_memory;
|
||||||
memreq_t memreq_common_memory;
|
memreq_t memreq_common_memory;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ipw->is_v2_card = 0;
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
p_dev->io.BasePort1 = cfg->io.win[0].base;
|
||||||
tuple.Attributes = 0;
|
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||||
tuple.TupleData = (cisdata_t *) buf;
|
p_dev->io.IOAddrLines = 16;
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
|
|
||||||
|
|
||||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
|
|
||||||
while (ret == 0) {
|
|
||||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, GetTupleData, ret);
|
|
||||||
goto exit0;
|
|
||||||
}
|
|
||||||
ret = pcmcia_get_next_tuple(link, &tuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
|
|
||||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, GetFirstTuple, ret);
|
|
||||||
goto exit0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, GetTupleData, ret);
|
|
||||||
goto exit0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, ParseTuple, ret);
|
|
||||||
goto exit0;
|
|
||||||
}
|
|
||||||
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
|
|
||||||
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
|
|
||||||
link->io.IOAddrLines = 16;
|
|
||||||
|
|
||||||
link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
|
|
||||||
|
|
||||||
/* 0x40 causes it to generate level mode interrupts. */
|
/* 0x40 causes it to generate level mode interrupts. */
|
||||||
/* 0x04 enables IREQ pin. */
|
/* 0x04 enables IREQ pin. */
|
||||||
cor_value = parse.cftable_entry.index | 0x44;
|
p_dev->conf.ConfigIndex = cfg->index | 0x44;
|
||||||
link->conf.ConfigIndex = cor_value;
|
ret = pcmcia_request_io(p_dev, &p_dev->io);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* IRQ and I/O settings */
|
io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1,
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
IPWIRELESS_PCCARD_NAME);
|
||||||
|
|
||||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
if (cfg->mem.nwin == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ret != 0) {
|
ipw->request_common_memory.Attributes =
|
||||||
cs_error(link, GetFirstTuple, ret);
|
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
|
||||||
goto exit0;
|
ipw->request_common_memory.Base = cfg->mem.win[0].host_addr;
|
||||||
}
|
ipw->request_common_memory.Size = cfg->mem.win[0].len;
|
||||||
|
if (ipw->request_common_memory.Size < 0x1000)
|
||||||
|
ipw->request_common_memory.Size = 0x1000;
|
||||||
|
ipw->request_common_memory.AccessSpeed = 0;
|
||||||
|
|
||||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
ret = pcmcia_request_window(p_dev, &ipw->request_common_memory,
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, GetTupleData, ret);
|
|
||||||
goto exit0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, GetTupleData, ret);
|
|
||||||
goto exit0;
|
|
||||||
}
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
|
||||||
link->conf.ConfigBase = parse.config.base;
|
|
||||||
link->conf.Present = parse.config.rmask[0];
|
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
|
||||||
|
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
|
||||||
link->irq.Handler = ipwireless_interrupt;
|
|
||||||
link->irq.Instance = ipw->hardware;
|
|
||||||
|
|
||||||
ret = pcmcia_request_io(link, &link->io);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, RequestIO, ret);
|
|
||||||
goto exit0;
|
|
||||||
}
|
|
||||||
|
|
||||||
request_region(link->io.BasePort1, link->io.NumPorts1,
|
|
||||||
IPWIRELESS_PCCARD_NAME);
|
|
||||||
|
|
||||||
/* memory settings */
|
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
|
|
||||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, GetFirstTuple, ret);
|
|
||||||
goto exit1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, GetTupleData, ret);
|
|
||||||
goto exit1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
cs_error(link, ParseTuple, ret);
|
|
||||||
goto exit1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parse.cftable_entry.mem.nwin > 0) {
|
|
||||||
ipw->request_common_memory.Attributes =
|
|
||||||
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
|
|
||||||
ipw->request_common_memory.Base =
|
|
||||||
parse.cftable_entry.mem.win[0].host_addr;
|
|
||||||
ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
|
|
||||||
if (ipw->request_common_memory.Size < 0x1000)
|
|
||||||
ipw->request_common_memory.Size = 0x1000;
|
|
||||||
ipw->request_common_memory.AccessSpeed = 0;
|
|
||||||
|
|
||||||
ret = pcmcia_request_window(&link, &ipw->request_common_memory,
|
|
||||||
&ipw->handle_common_memory);
|
&ipw->handle_common_memory);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, RequestWindow, ret);
|
goto exit1;
|
||||||
goto exit1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memreq_common_memory.CardOffset =
|
memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr;
|
||||||
parse.cftable_entry.mem.win[0].card_addr;
|
memreq_common_memory.Page = 0;
|
||||||
memreq_common_memory.Page = 0;
|
|
||||||
|
|
||||||
ret = pcmcia_map_mem_page(ipw->handle_common_memory,
|
ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory,
|
||||||
&memreq_common_memory);
|
&memreq_common_memory);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, MapMemPage, ret);
|
goto exit2;
|
||||||
goto exit1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipw->is_v2_card =
|
ipw->is_v2_card = cfg->mem.win[0].len == 0x100;
|
||||||
parse.cftable_entry.mem.win[0].len == 0x100;
|
|
||||||
|
|
||||||
ipw->common_memory = ioremap(ipw->request_common_memory.Base,
|
ipw->common_memory = ioremap(ipw->request_common_memory.Base,
|
||||||
ipw->request_common_memory.Size);
|
ipw->request_common_memory.Size);
|
||||||
request_mem_region(ipw->request_common_memory.Base,
|
request_mem_region(ipw->request_common_memory.Base,
|
||||||
ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);
|
ipw->request_common_memory.Size,
|
||||||
|
IPWIRELESS_PCCARD_NAME);
|
||||||
|
|
||||||
ipw->request_attr_memory.Attributes =
|
ipw->request_attr_memory.Attributes =
|
||||||
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
|
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
|
||||||
ipw->request_attr_memory.Base = 0;
|
ipw->request_attr_memory.Base = 0;
|
||||||
ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
|
ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
|
||||||
ipw->request_attr_memory.AccessSpeed = 0;
|
ipw->request_attr_memory.AccessSpeed = 0;
|
||||||
|
|
||||||
ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
|
ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory,
|
||||||
&ipw->handle_attr_memory);
|
&ipw->handle_attr_memory);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, RequestWindow, ret);
|
goto exit2;
|
||||||
goto exit2;
|
|
||||||
}
|
|
||||||
|
|
||||||
memreq_attr_memory.CardOffset = 0;
|
memreq_attr_memory.CardOffset = 0;
|
||||||
memreq_attr_memory.Page = 0;
|
memreq_attr_memory.Page = 0;
|
||||||
|
|
||||||
ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
|
ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory,
|
||||||
&memreq_attr_memory);
|
&memreq_attr_memory);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, MapMemPage, ret);
|
goto exit3;
|
||||||
goto exit2;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
|
ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
|
||||||
ipw->request_attr_memory.Size);
|
ipw->request_attr_memory.Size);
|
||||||
request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
|
request_mem_region(ipw->request_attr_memory.Base,
|
||||||
IPWIRELESS_PCCARD_NAME);
|
ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME);
|
||||||
}
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
exit3:
|
||||||
|
pcmcia_release_window(p_dev, ipw->handle_attr_memory);
|
||||||
|
exit2:
|
||||||
|
if (ipw->common_memory) {
|
||||||
|
release_mem_region(ipw->request_common_memory.Base,
|
||||||
|
ipw->request_common_memory.Size);
|
||||||
|
iounmap(ipw->common_memory);
|
||||||
|
pcmcia_release_window(p_dev, ipw->handle_common_memory);
|
||||||
|
} else
|
||||||
|
pcmcia_release_window(p_dev, ipw->handle_common_memory);
|
||||||
|
exit1:
|
||||||
|
release_resource(io_resource);
|
||||||
|
pcmcia_disable_device(p_dev);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_ipwireless(struct ipw_dev *ipw)
|
||||||
|
{
|
||||||
|
struct pcmcia_device *link = ipw->link;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ipw->is_v2_card = 0;
|
||||||
|
|
||||||
|
ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
|
link->irq.Handler = ipwireless_interrupt;
|
||||||
|
|
||||||
INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
|
INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
|
||||||
|
|
||||||
@ -291,10 +207,8 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||||||
|
|
||||||
ret = pcmcia_request_irq(link, &link->irq);
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, RequestIRQ, ret);
|
goto exit;
|
||||||
goto exit3;
|
|
||||||
}
|
|
||||||
|
|
||||||
printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
|
printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
|
||||||
ipw->is_v2_card ? "V2/V3" : "V1");
|
ipw->is_v2_card ? "V2/V3" : "V1");
|
||||||
@ -316,12 +230,12 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||||||
|
|
||||||
ipw->network = ipwireless_network_create(ipw->hardware);
|
ipw->network = ipwireless_network_create(ipw->hardware);
|
||||||
if (!ipw->network)
|
if (!ipw->network)
|
||||||
goto exit3;
|
goto exit;
|
||||||
|
|
||||||
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
|
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
|
||||||
ipw->nodes);
|
ipw->nodes);
|
||||||
if (!ipw->tty)
|
if (!ipw->tty)
|
||||||
goto exit3;
|
goto exit;
|
||||||
|
|
||||||
ipwireless_init_hardware_v2_v3(ipw->hardware);
|
ipwireless_init_hardware_v2_v3(ipw->hardware);
|
||||||
|
|
||||||
@ -331,35 +245,27 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||||||
*/
|
*/
|
||||||
ret = pcmcia_request_configuration(link, &link->conf);
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, RequestConfiguration, ret);
|
goto exit;
|
||||||
goto exit4;
|
|
||||||
}
|
|
||||||
|
|
||||||
link->dev_node = &ipw->nodes[0];
|
link->dev_node = &ipw->nodes[0];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit4:
|
exit:
|
||||||
pcmcia_disable_device(link);
|
|
||||||
exit3:
|
|
||||||
if (ipw->attr_memory) {
|
if (ipw->attr_memory) {
|
||||||
release_mem_region(ipw->request_attr_memory.Base,
|
release_mem_region(ipw->request_attr_memory.Base,
|
||||||
ipw->request_attr_memory.Size);
|
ipw->request_attr_memory.Size);
|
||||||
iounmap(ipw->attr_memory);
|
iounmap(ipw->attr_memory);
|
||||||
pcmcia_release_window(ipw->handle_attr_memory);
|
pcmcia_release_window(link, ipw->handle_attr_memory);
|
||||||
pcmcia_disable_device(link);
|
|
||||||
}
|
}
|
||||||
exit2:
|
|
||||||
if (ipw->common_memory) {
|
if (ipw->common_memory) {
|
||||||
release_mem_region(ipw->request_common_memory.Base,
|
release_mem_region(ipw->request_common_memory.Base,
|
||||||
ipw->request_common_memory.Size);
|
ipw->request_common_memory.Size);
|
||||||
iounmap(ipw->common_memory);
|
iounmap(ipw->common_memory);
|
||||||
pcmcia_release_window(ipw->handle_common_memory);
|
pcmcia_release_window(link, ipw->handle_common_memory);
|
||||||
}
|
}
|
||||||
exit1:
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
exit0:
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,9 +284,9 @@ static void release_ipwireless(struct ipw_dev *ipw)
|
|||||||
iounmap(ipw->attr_memory);
|
iounmap(ipw->attr_memory);
|
||||||
}
|
}
|
||||||
if (ipw->common_memory)
|
if (ipw->common_memory)
|
||||||
pcmcia_release_window(ipw->handle_common_memory);
|
pcmcia_release_window(ipw->link, ipw->handle_common_memory);
|
||||||
if (ipw->attr_memory)
|
if (ipw->attr_memory)
|
||||||
pcmcia_release_window(ipw->handle_attr_memory);
|
pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
|
||||||
|
|
||||||
/* Break the link with Card Services */
|
/* Break the link with Card Services */
|
||||||
pcmcia_disable_device(ipw->link);
|
pcmcia_disable_device(ipw->link);
|
||||||
@ -406,7 +312,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
ipw->link = link;
|
ipw->link = link;
|
||||||
link->priv = ipw;
|
link->priv = ipw;
|
||||||
link->irq.Instance = ipw;
|
|
||||||
|
|
||||||
/* Link this device into our device list. */
|
/* Link this device into our device list. */
|
||||||
link->dev_node = &ipw->nodes[0];
|
link->dev_node = &ipw->nodes[0];
|
||||||
@ -421,7 +326,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
|
|||||||
ret = config_ipwireless(ipw);
|
ret = config_ipwireless(ipw);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
cs_error(link, RegisterClient, ret);
|
|
||||||
ipwireless_detach(link);
|
ipwireless_detach(link);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
link->conf.Attributes = 0;
|
link->conf.Attributes = 0;
|
||||||
@ -572,69 +571,51 @@ static int mgslpc_probe(struct pcmcia_device *link)
|
|||||||
/* Card has been inserted.
|
/* Card has been inserted.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
if (cfg->io.nwin > 0) {
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
if (!(cfg->io.flags & CISTPL_IO_8BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
|
if (!(cfg->io.flags & CISTPL_IO_16BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
|
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
|
||||||
|
p_dev->io.BasePort1 = cfg->io.win[0].base;
|
||||||
|
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||||
|
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||||
|
}
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
static int mgslpc_config(struct pcmcia_device *link)
|
static int mgslpc_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
MGSLPC_INFO *info = link->priv;
|
MGSLPC_INFO *info = link->priv;
|
||||||
tuple_t tuple;
|
int ret;
|
||||||
cisparse_t parse;
|
|
||||||
int last_fn, last_ret;
|
|
||||||
u_char buf[64];
|
|
||||||
cistpl_cftable_entry_t dflt = { 0 };
|
|
||||||
cistpl_cftable_entry_t *cfg;
|
|
||||||
|
|
||||||
if (debug_level >= DEBUG_LEVEL_INFO)
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
||||||
printk("mgslpc_config(0x%p)\n", link);
|
printk("mgslpc_config(0x%p)\n", link);
|
||||||
|
|
||||||
tuple.Attributes = 0;
|
ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
|
||||||
tuple.TupleData = buf;
|
if (ret != 0)
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
goto failed;
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
/* get CIS configuration entry */
|
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
|
||||||
|
|
||||||
cfg = &(parse.cftable_entry);
|
|
||||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
|
||||||
CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
|
|
||||||
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
|
|
||||||
if (cfg->index == 0)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
link->conf.ConfigIndex = cfg->index;
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
|
||||||
|
|
||||||
/* IO window settings */
|
|
||||||
link->io.NumPorts1 = 0;
|
|
||||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
|
||||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
if (!(io->flags & CISTPL_IO_8BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
|
||||||
if (!(io->flags & CISTPL_IO_16BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
|
||||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
|
||||||
link->io.BasePort1 = io->win[0].base;
|
|
||||||
link->io.NumPorts1 = io->win[0].len;
|
|
||||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
|
||||||
}
|
|
||||||
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.ConfigIndex = 8;
|
link->conf.ConfigIndex = 8;
|
||||||
link->conf.Present = PRESENT_OPTION;
|
link->conf.Present = PRESENT_OPTION;
|
||||||
|
|
||||||
link->irq.Attributes |= IRQ_HANDLE_PRESENT;
|
|
||||||
link->irq.Handler = mgslpc_isr;
|
link->irq.Handler = mgslpc_isr;
|
||||||
link->irq.Instance = info;
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
|
||||||
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
info->io_base = link->io.BasePort1;
|
info->io_base = link->io.BasePort1;
|
||||||
info->irq_level = link->irq.AssignedIRQ;
|
info->irq_level = link->irq.AssignedIRQ;
|
||||||
@ -654,8 +635,7 @@ static int mgslpc_config(struct pcmcia_device *link)
|
|||||||
printk("\n");
|
printk("\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
mgslpc_release((u_long)link);
|
mgslpc_release((u_long)link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -60,15 +60,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
|||||||
MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
|
MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
|
||||||
MODULE_LICENSE("Dual MPL/GPL");
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
|
|
||||||
#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
INT_MODULE_PARM(pc_debug, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
typedef struct ide_info_t {
|
typedef struct ide_info_t {
|
||||||
@ -98,7 +89,7 @@ static int ide_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
ide_info_t *info;
|
ide_info_t *info;
|
||||||
|
|
||||||
DEBUG(0, "ide_attach()\n");
|
dev_dbg(&link->dev, "ide_attach()\n");
|
||||||
|
|
||||||
/* Create new ide device */
|
/* Create new ide device */
|
||||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||||
@ -112,7 +103,6 @@ static int ide_probe(struct pcmcia_device *link)
|
|||||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.IOAddrLines = 3;
|
link->io.IOAddrLines = 3;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -134,7 +124,7 @@ static void ide_detach(struct pcmcia_device *link)
|
|||||||
ide_hwif_t *hwif = info->host->ports[0];
|
ide_hwif_t *hwif = info->host->ports[0];
|
||||||
unsigned long data_addr, ctl_addr;
|
unsigned long data_addr, ctl_addr;
|
||||||
|
|
||||||
DEBUG(0, "ide_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
|
||||||
|
|
||||||
data_addr = hwif->io_ports.data_addr;
|
data_addr = hwif->io_ports.data_addr;
|
||||||
ctl_addr = hwif->io_ports.ctl_addr;
|
ctl_addr = hwif->io_ports.ctl_addr;
|
||||||
@ -217,9 +207,6 @@ static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
struct pcmcia_config_check {
|
struct pcmcia_config_check {
|
||||||
unsigned long ctl_base;
|
unsigned long ctl_base;
|
||||||
int skip_vcc;
|
int skip_vcc;
|
||||||
@ -282,11 +269,11 @@ static int ide_config(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
ide_info_t *info = link->priv;
|
ide_info_t *info = link->priv;
|
||||||
struct pcmcia_config_check *stk = NULL;
|
struct pcmcia_config_check *stk = NULL;
|
||||||
int last_ret = 0, last_fn = 0, is_kme = 0;
|
int ret = 0, is_kme = 0;
|
||||||
unsigned long io_base, ctl_base;
|
unsigned long io_base, ctl_base;
|
||||||
struct ide_host *host;
|
struct ide_host *host;
|
||||||
|
|
||||||
DEBUG(0, "ide_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
|
||||||
|
|
||||||
is_kme = ((link->manf_id == MANFID_KME) &&
|
is_kme = ((link->manf_id == MANFID_KME) &&
|
||||||
((link->card_id == PRODID_KME_KXLC005_A) ||
|
((link->card_id == PRODID_KME_KXLC005_A) ||
|
||||||
@ -306,8 +293,12 @@ static int ide_config(struct pcmcia_device *link)
|
|||||||
io_base = link->io.BasePort1;
|
io_base = link->io.BasePort1;
|
||||||
ctl_base = stk->ctl_base;
|
ctl_base = stk->ctl_base;
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* disable drive interrupts during IDE probe */
|
/* disable drive interrupts during IDE probe */
|
||||||
outb(0x02, ctl_base);
|
outb(0x02, ctl_base);
|
||||||
@ -342,8 +333,6 @@ static int ide_config(struct pcmcia_device *link)
|
|||||||
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
|
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
kfree(stk);
|
kfree(stk);
|
||||||
ide_release(link);
|
ide_release(link);
|
||||||
@ -363,7 +352,7 @@ static void ide_release(struct pcmcia_device *link)
|
|||||||
ide_info_t *info = link->priv;
|
ide_info_t *info = link->priv;
|
||||||
struct ide_host *host = info->host;
|
struct ide_host *host = info->host;
|
||||||
|
|
||||||
DEBUG(0, "ide_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
|
||||||
|
|
||||||
if (info->ndev)
|
if (info->ndev)
|
||||||
/* FIXME: if this fails we need to queue the cleanup somehow
|
/* FIXME: if this fails we need to queue the cleanup somehow
|
||||||
|
@ -111,8 +111,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
|
|||||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
|
|
||||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
/* General socket configuration */
|
/* General socket configuration */
|
||||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
@ -198,7 +196,6 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||||||
*/
|
*/
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
/* undo */
|
/* undo */
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
break;
|
break;
|
||||||
@ -209,7 +206,6 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||||||
*/
|
*/
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -30,22 +30,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA car
|
|||||||
MODULE_AUTHOR("Carsten Paeth");
|
MODULE_AUTHOR("Carsten Paeth");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
|
||||||
static char *version =
|
|
||||||
"avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -119,7 +103,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
|
|||||||
{
|
{
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "avma1cs_attach()\n");
|
dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||||
@ -139,8 +123,6 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
|
|||||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
|
|
||||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
/* General socket configuration */
|
/* General socket configuration */
|
||||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
@ -161,7 +143,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
|
|||||||
|
|
||||||
static void avma1cs_detach(struct pcmcia_device *link)
|
static void avma1cs_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "avma1cs_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
|
||||||
avma1cs_release(link);
|
avma1cs_release(link);
|
||||||
kfree(link->priv);
|
kfree(link->priv);
|
||||||
} /* avma1cs_detach */
|
} /* avma1cs_detach */
|
||||||
@ -203,7 +185,7 @@ static int avma1cs_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
dev = link->priv;
|
dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "avma1cs_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
|
||||||
|
|
||||||
devname[0] = 0;
|
devname[0] = 0;
|
||||||
if (link->prod_id[1])
|
if (link->prod_id[1])
|
||||||
@ -218,7 +200,6 @@ static int avma1cs_config(struct pcmcia_device *link)
|
|||||||
*/
|
*/
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
/* undo */
|
/* undo */
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
break;
|
break;
|
||||||
@ -229,7 +210,6 @@ static int avma1cs_config(struct pcmcia_device *link)
|
|||||||
*/
|
*/
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -281,7 +261,7 @@ static void avma1cs_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *local = link->priv;
|
local_info_t *local = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "avma1cs_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
|
||||||
|
|
||||||
/* now unregister function with hisax */
|
/* now unregister function with hisax */
|
||||||
HiSax_closecard(local->node.minor);
|
HiSax_closecard(local->node.minor);
|
||||||
|
@ -57,23 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
|
|||||||
MODULE_AUTHOR("Klaus Lichtenwalder");
|
MODULE_AUTHOR("Klaus Lichtenwalder");
|
||||||
MODULE_LICENSE("Dual MPL/GPL");
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
|
||||||
static char *version =
|
|
||||||
"elsa_cs.c $Revision: 1.2.2.4 $ $Date: 2004/01/25 15:07:06 $ (K.Lichtenwalder)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -142,7 +125,7 @@ static int elsa_cs_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "elsa_cs_attach()\n");
|
dev_dbg(&link->dev, "elsa_cs_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||||
@ -155,7 +138,6 @@ static int elsa_cs_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -188,7 +170,7 @@ static void elsa_cs_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *info = link->priv;
|
local_info_t *info = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
|
||||||
|
|
||||||
info->busy = 1;
|
info->busy = 1;
|
||||||
elsa_cs_release(link);
|
elsa_cs_release(link);
|
||||||
@ -231,30 +213,25 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
|
|||||||
static int elsa_cs_config(struct pcmcia_device *link)
|
static int elsa_cs_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
local_info_t *dev;
|
local_info_t *dev;
|
||||||
int i, last_fn;
|
int i;
|
||||||
IsdnCard_t icard;
|
IsdnCard_t icard;
|
||||||
|
|
||||||
DEBUG(0, "elsa_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
|
||||||
dev = link->priv;
|
dev = link->priv;
|
||||||
|
|
||||||
i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
|
i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
last_fn = RequestIO;
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
last_fn = RequestIRQ;
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
last_fn = RequestConfiguration;
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* At this point, the dev_node_t structure(s) should be
|
/* At this point, the dev_node_t structure(s) should be
|
||||||
initialized and arranged in a linked list at link->dev. *//* */
|
initialized and arranged in a linked list at link->dev. *//* */
|
||||||
@ -290,8 +267,7 @@ static int elsa_cs_config(struct pcmcia_device *link)
|
|||||||
((local_info_t*)link->priv)->cardnr = i;
|
((local_info_t*)link->priv)->cardnr = i;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
cs_failed:
|
failed:
|
||||||
cs_error(link, last_fn, i);
|
|
||||||
elsa_cs_release(link);
|
elsa_cs_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} /* elsa_cs_config */
|
} /* elsa_cs_config */
|
||||||
@ -308,7 +284,7 @@ static void elsa_cs_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *local = link->priv;
|
local_info_t *local = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "elsa_cs_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
if (local->cardnr >= 0) {
|
if (local->cardnr >= 0) {
|
||||||
|
@ -57,24 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
|
|||||||
MODULE_AUTHOR("Marcus Niemann");
|
MODULE_AUTHOR("Marcus Niemann");
|
||||||
MODULE_LICENSE("Dual MPL/GPL");
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
|
||||||
static char *version =
|
|
||||||
"sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -151,7 +133,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "sedlbauer_attach()\n");
|
dev_dbg(&link->dev, "sedlbauer_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||||
@ -163,7 +145,6 @@ static int sedlbauer_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -198,7 +179,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void sedlbauer_detach(struct pcmcia_device *link)
|
static void sedlbauer_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
|
||||||
|
|
||||||
((local_info_t *)link->priv)->stop = 1;
|
((local_info_t *)link->priv)->stop = 1;
|
||||||
sedlbauer_release(link);
|
sedlbauer_release(link);
|
||||||
@ -214,9 +195,6 @@ static void sedlbauer_detach(struct pcmcia_device *link)
|
|||||||
device available to the system.
|
device available to the system.
|
||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -293,11 +271,11 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
|||||||
req->Base = mem->win[0].host_addr;
|
req->Base = mem->win[0].host_addr;
|
||||||
req->Size = mem->win[0].len;
|
req->Size = mem->win[0].len;
|
||||||
req->AccessSpeed = 0;
|
req->AccessSpeed = 0;
|
||||||
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
|
if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
map.Page = 0;
|
map.Page = 0;
|
||||||
map.CardOffset = mem->win[0].card_addr;
|
map.CardOffset = mem->win[0].card_addr;
|
||||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -309,10 +287,10 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *dev = link->priv;
|
local_info_t *dev = link->priv;
|
||||||
win_req_t *req;
|
win_req_t *req;
|
||||||
int last_fn, last_ret;
|
int ret;
|
||||||
IsdnCard_t icard;
|
IsdnCard_t icard;
|
||||||
|
|
||||||
DEBUG(0, "sedlbauer_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
|
||||||
|
|
||||||
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
||||||
if (!req)
|
if (!req)
|
||||||
@ -330,8 +308,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||||||
these things without consulting the CIS, and most client drivers
|
these things without consulting the CIS, and most client drivers
|
||||||
will only use the CIS to fill in implementation-defined details.
|
will only use the CIS to fill in implementation-defined details.
|
||||||
*/
|
*/
|
||||||
last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
|
ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
|
||||||
if (last_ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -339,15 +317,20 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||||||
handler to the interrupt, unless the 'Handler' member of the
|
handler to the interrupt, unless the 'Handler' member of the
|
||||||
irq structure is initialized.
|
irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This actually configures the PCMCIA socket -- setting up
|
This actually configures the PCMCIA socket -- setting up
|
||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At this point, the dev_node_t structure(s) need to be
|
At this point, the dev_node_t structure(s) need to be
|
||||||
@ -380,19 +363,18 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||||||
icard.protocol = protocol;
|
icard.protocol = protocol;
|
||||||
icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
|
icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
|
||||||
|
|
||||||
last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard);
|
ret = hisax_init_pcmcia(link,
|
||||||
if (last_ret < 0) {
|
&(((local_info_t *)link->priv)->stop), &icard);
|
||||||
printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
|
if (ret < 0) {
|
||||||
last_ret, link->io.BasePort1);
|
printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
|
||||||
|
ret, link->io.BasePort1);
|
||||||
sedlbauer_release(link);
|
sedlbauer_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else
|
} else
|
||||||
((local_info_t*)link->priv)->cardnr = last_ret;
|
((local_info_t *)link->priv)->cardnr = ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
sedlbauer_release(link);
|
sedlbauer_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -410,7 +392,7 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||||||
static void sedlbauer_release(struct pcmcia_device *link)
|
static void sedlbauer_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
local_info_t *local = link->priv;
|
local_info_t *local = link->priv;
|
||||||
DEBUG(0, "sedlbauer_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
if (local->cardnr >= 0) {
|
if (local->cardnr >= 0) {
|
||||||
|
@ -38,23 +38,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards");
|
|||||||
MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
|
MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
|
||||||
static char *version =
|
|
||||||
"teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -133,7 +116,7 @@ static int teles_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "teles_attach()\n");
|
dev_dbg(&link->dev, "teles_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||||
@ -145,7 +128,6 @@ static int teles_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -178,7 +160,7 @@ static void teles_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *info = link->priv;
|
local_info_t *info = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "teles_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "teles_detach(0x%p)\n", link);
|
||||||
|
|
||||||
info->busy = 1;
|
info->busy = 1;
|
||||||
teles_cs_release(link);
|
teles_cs_release(link);
|
||||||
@ -221,30 +203,25 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
|
|||||||
static int teles_cs_config(struct pcmcia_device *link)
|
static int teles_cs_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
local_info_t *dev;
|
local_info_t *dev;
|
||||||
int i, last_fn;
|
int i;
|
||||||
IsdnCard_t icard;
|
IsdnCard_t icard;
|
||||||
|
|
||||||
DEBUG(0, "teles_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
|
||||||
dev = link->priv;
|
dev = link->priv;
|
||||||
|
|
||||||
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
|
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
last_fn = RequestIO;
|
|
||||||
goto cs_failed;
|
goto cs_failed;
|
||||||
}
|
|
||||||
|
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
last_fn = RequestIRQ;
|
|
||||||
goto cs_failed;
|
goto cs_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
last_fn = RequestConfiguration;
|
|
||||||
goto cs_failed;
|
goto cs_failed;
|
||||||
}
|
|
||||||
|
|
||||||
/* At this point, the dev_node_t structure(s) should be
|
/* At this point, the dev_node_t structure(s) should be
|
||||||
initialized and arranged in a linked list at link->dev. *//* */
|
initialized and arranged in a linked list at link->dev. *//* */
|
||||||
@ -283,7 +260,6 @@ static int teles_cs_config(struct pcmcia_device *link)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
cs_failed:
|
||||||
cs_error(link, last_fn, i);
|
|
||||||
teles_cs_release(link);
|
teles_cs_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} /* teles_cs_config */
|
} /* teles_cs_config */
|
||||||
@ -300,7 +276,7 @@ static void teles_cs_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *local = link->priv;
|
local_info_t *local = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "teles_cs_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
if (local->cardnr >= 0) {
|
if (local->cardnr >= 0) {
|
||||||
|
@ -118,11 +118,9 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
|
|||||||
DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
|
DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
|
||||||
dev->offset, mrq.CardOffset);
|
dev->offset, mrq.CardOffset);
|
||||||
mrq.Page = 0;
|
mrq.Page = 0;
|
||||||
ret = pcmcia_map_mem_page(win, &mrq);
|
ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq);
|
||||||
if (ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(dev->p_dev, MapMemPage, ret);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
dev->offset = mrq.CardOffset;
|
dev->offset = mrq.CardOffset;
|
||||||
}
|
}
|
||||||
return dev->win_base + (to & (dev->win_size-1));
|
return dev->win_base + (to & (dev->win_size-1));
|
||||||
@ -327,8 +325,6 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
|
|||||||
|
|
||||||
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
|
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
|
||||||
ret = pcmcia_modify_configuration(link, &mod);
|
ret = pcmcia_modify_configuration(link, &mod);
|
||||||
if (ret != 0)
|
|
||||||
cs_error(link, ModifyConfiguration, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -348,107 +344,116 @@ static void pcmciamtd_release(struct pcmcia_device *link)
|
|||||||
iounmap(dev->win_base);
|
iounmap(dev->win_base);
|
||||||
dev->win_base = NULL;
|
dev->win_base = NULL;
|
||||||
}
|
}
|
||||||
pcmcia_release_window(link->win);
|
pcmcia_release_window(link, link->win);
|
||||||
}
|
}
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTD_DEBUG
|
||||||
|
static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
cisparse_t parse;
|
||||||
|
|
||||||
|
if (!pcmcia_parse_tuple(tuple, &parse)) {
|
||||||
|
cistpl_format_t *t = &parse.format;
|
||||||
|
(void)t; /* Shut up, gcc */
|
||||||
|
DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
|
||||||
|
t->type, t->edc, t->offset, t->length);
|
||||||
|
}
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
cisparse_t parse;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!pcmcia_parse_tuple(tuple, &parse)) {
|
||||||
|
cistpl_jedec_t *t = &parse.jedec;
|
||||||
|
for (i = 0; i < t->nid; i++)
|
||||||
|
DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
|
||||||
|
}
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
struct pcmciamtd_dev *dev = priv_data;
|
||||||
|
cisparse_t parse;
|
||||||
|
cistpl_device_t *t = &parse.device;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (pcmcia_parse_tuple(tuple, &parse))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
DEBUG(2, "Common memory:");
|
||||||
|
dev->pcmcia_map.size = t->dev[0].size;
|
||||||
|
/* from here on: DEBUG only */
|
||||||
|
for (i = 0; i < t->ndev; i++) {
|
||||||
|
DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
|
||||||
|
DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
|
||||||
|
DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
|
||||||
|
DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
struct pcmciamtd_dev *dev = priv_data;
|
||||||
|
cisparse_t parse;
|
||||||
|
cistpl_device_geo_t *t = &parse.device_geo;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (pcmcia_parse_tuple(tuple, &parse))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
|
||||||
|
/* from here on: DEBUG only */
|
||||||
|
for (i = 0; i < t->ngeo; i++) {
|
||||||
|
DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
|
||||||
|
DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
|
||||||
|
DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
|
||||||
|
DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
|
||||||
|
DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
|
||||||
|
DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
|
static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
|
||||||
{
|
{
|
||||||
int rc;
|
int i;
|
||||||
tuple_t tuple;
|
|
||||||
cisparse_t parse;
|
|
||||||
u_char buf[64];
|
|
||||||
|
|
||||||
tuple.Attributes = 0;
|
if (p_dev->prod_id[0]) {
|
||||||
tuple.TupleData = (cisdata_t *)buf;
|
dev->mtd_name[0] = '\0';
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
for (i = 0; i < 4; i++) {
|
||||||
tuple.TupleOffset = 0;
|
if (i)
|
||||||
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
|
strcat(dev->mtd_name, " ");
|
||||||
|
if (p_dev->prod_id[i])
|
||||||
rc = pcmcia_get_first_tuple(link, &tuple);
|
strcat(dev->mtd_name, p_dev->prod_id[i]);
|
||||||
while (rc == 0) {
|
|
||||||
rc = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
if (rc != 0) {
|
|
||||||
cs_error(link, GetTupleData, rc);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
rc = pcmcia_parse_tuple(&tuple, &parse);
|
DEBUG(2, "Found name: %s", dev->mtd_name);
|
||||||
if (rc != 0) {
|
|
||||||
cs_error(link, ParseTuple, rc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(tuple.TupleCode) {
|
|
||||||
case CISTPL_FORMAT: {
|
|
||||||
cistpl_format_t *t = &parse.format;
|
|
||||||
(void)t; /* Shut up, gcc */
|
|
||||||
DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
|
|
||||||
t->type, t->edc, t->offset, t->length);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
case CISTPL_DEVICE: {
|
|
||||||
cistpl_device_t *t = &parse.device;
|
|
||||||
int i;
|
|
||||||
DEBUG(2, "Common memory:");
|
|
||||||
dev->pcmcia_map.size = t->dev[0].size;
|
|
||||||
for(i = 0; i < t->ndev; i++) {
|
|
||||||
DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
|
|
||||||
DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
|
|
||||||
DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
|
|
||||||
DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CISTPL_VERS_1: {
|
|
||||||
cistpl_vers_1_t *t = &parse.version_1;
|
|
||||||
int i;
|
|
||||||
if(t->ns) {
|
|
||||||
dev->mtd_name[0] = '\0';
|
|
||||||
for(i = 0; i < t->ns; i++) {
|
|
||||||
if(i)
|
|
||||||
strcat(dev->mtd_name, " ");
|
|
||||||
strcat(dev->mtd_name, t->str+t->ofs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUG(2, "Found name: %s", dev->mtd_name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CISTPL_JEDEC_C: {
|
|
||||||
cistpl_jedec_t *t = &parse.jedec;
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < t->nid; i++) {
|
|
||||||
DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CISTPL_DEVICE_GEO: {
|
|
||||||
cistpl_device_geo_t *t = &parse.device_geo;
|
|
||||||
int i;
|
|
||||||
dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
|
|
||||||
for(i = 0; i < t->ngeo; i++) {
|
|
||||||
DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
|
|
||||||
DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
|
|
||||||
DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
|
|
||||||
DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
|
|
||||||
DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
|
|
||||||
DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = pcmcia_get_next_tuple(link, &tuple);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTD_DEBUG
|
||||||
|
pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
|
||||||
|
pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
|
||||||
|
#endif
|
||||||
|
pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
|
||||||
|
pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
|
||||||
|
|
||||||
if(!dev->pcmcia_map.size)
|
if(!dev->pcmcia_map.size)
|
||||||
dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
|
dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
|
||||||
|
|
||||||
@ -481,16 +486,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link,
|
|||||||
* MTD device available to the system.
|
* MTD device available to the system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int pcmciamtd_config(struct pcmcia_device *link)
|
static int pcmciamtd_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct pcmciamtd_dev *dev = link->priv;
|
struct pcmciamtd_dev *dev = link->priv;
|
||||||
struct mtd_info *mtd = NULL;
|
struct mtd_info *mtd = NULL;
|
||||||
cs_status_t status;
|
cs_status_t status;
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
int last_ret = 0, last_fn = 0;
|
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
static char *probes[] = { "jedec_probe", "cfi_probe" };
|
static char *probes[] = { "jedec_probe", "cfi_probe" };
|
||||||
@ -529,7 +530,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
|
|||||||
int ret;
|
int ret;
|
||||||
DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
|
DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
|
||||||
req.Size >> 10, req.AccessSpeed);
|
req.Size >> 10, req.AccessSpeed);
|
||||||
ret = pcmcia_request_window(&link, &req, &link->win);
|
ret = pcmcia_request_window(link, &req, &link->win);
|
||||||
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
|
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
req.Size >>= 1;
|
req.Size >>= 1;
|
||||||
@ -577,7 +578,6 @@ static int pcmciamtd_config(struct pcmcia_device *link)
|
|||||||
DEBUG(2, "Setting Configuration");
|
DEBUG(2, "Setting Configuration");
|
||||||
ret = pcmcia_request_configuration(link, &link->conf);
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
cs_error(link, RequestConfiguration, ret);
|
|
||||||
if (dev->win_base) {
|
if (dev->win_base) {
|
||||||
iounmap(dev->win_base);
|
iounmap(dev->win_base);
|
||||||
dev->win_base = NULL;
|
dev->win_base = NULL;
|
||||||
@ -652,8 +652,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
|
|||||||
link->dev_node = &dev->node;
|
link->dev_node = &dev->node;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
err("CS Error, exiting");
|
err("CS Error, exiting");
|
||||||
pcmciamtd_release(link);
|
pcmciamtd_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -118,14 +118,6 @@ INT_MODULE_PARM(full_duplex, 0);
|
|||||||
/* Autodetect link polarity reversal? */
|
/* Autodetect link polarity reversal? */
|
||||||
INT_MODULE_PARM(auto_polarity, 1);
|
INT_MODULE_PARM(auto_polarity, 1);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"3c574_cs.c 1.65ac1 2003/04/07 Donald Becker/David Hinds, becker@scyld.com.\n";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -278,7 +270,7 @@ static int tc574_probe(struct pcmcia_device *link)
|
|||||||
struct el3_private *lp;
|
struct el3_private *lp;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
DEBUG(0, "3c574_attach()\n");
|
dev_dbg(&link->dev, "3c574_attach()\n");
|
||||||
|
|
||||||
/* Create the PC card device object. */
|
/* Create the PC card device object. */
|
||||||
dev = alloc_etherdev(sizeof(struct el3_private));
|
dev = alloc_etherdev(sizeof(struct el3_private));
|
||||||
@ -291,10 +283,8 @@ static int tc574_probe(struct pcmcia_device *link)
|
|||||||
spin_lock_init(&lp->window_lock);
|
spin_lock_init(&lp->window_lock);
|
||||||
link->io.NumPorts1 = 32;
|
link->io.NumPorts1 = 32;
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = &el3_interrupt;
|
link->irq.Handler = &el3_interrupt;
|
||||||
link->irq.Instance = dev;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.ConfigIndex = 1;
|
link->conf.ConfigIndex = 1;
|
||||||
@ -319,7 +309,7 @@ static void tc574_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "3c574_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "3c574_detach()\n");
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -335,26 +325,23 @@ static void tc574_detach(struct pcmcia_device *link)
|
|||||||
ethernet device available to the system.
|
ethernet device available to the system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
|
static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
|
||||||
|
|
||||||
static int tc574_config(struct pcmcia_device *link)
|
static int tc574_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
struct el3_private *lp = netdev_priv(dev);
|
struct el3_private *lp = netdev_priv(dev);
|
||||||
tuple_t tuple;
|
int ret, i, j;
|
||||||
__le16 buf[32];
|
|
||||||
int last_fn, last_ret, i, j;
|
|
||||||
unsigned int ioaddr;
|
unsigned int ioaddr;
|
||||||
__be16 *phys_addr;
|
__be16 *phys_addr;
|
||||||
char *cardname;
|
char *cardname;
|
||||||
__u32 config;
|
__u32 config;
|
||||||
|
u8 *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
phys_addr = (__be16 *)dev->dev_addr;
|
phys_addr = (__be16 *)dev->dev_addr;
|
||||||
|
|
||||||
DEBUG(0, "3c574_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "3c574_config()\n");
|
||||||
|
|
||||||
link->io.IOAddrLines = 16;
|
link->io.IOAddrLines = 16;
|
||||||
for (i = j = 0; j < 0x400; j += 0x20) {
|
for (i = j = 0; j < 0x400; j += 0x20) {
|
||||||
@ -363,12 +350,16 @@ static int tc574_config(struct pcmcia_device *link)
|
|||||||
if (i == 0)
|
if (i == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIO, i);
|
goto failed;
|
||||||
|
|
||||||
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
|
||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
@ -378,16 +369,14 @@ static int tc574_config(struct pcmcia_device *link)
|
|||||||
/* The 3c574 normally uses an EEPROM for configuration info, including
|
/* The 3c574 normally uses an EEPROM for configuration info, including
|
||||||
the hardware address. The future products may include a modem chip
|
the hardware address. The future products may include a modem chip
|
||||||
and put the address in the CIS. */
|
and put the address in the CIS. */
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = (cisdata_t *)buf;
|
len = pcmcia_get_tuple(link, 0x88, &buf);
|
||||||
tuple.TupleDataMax = 64;
|
if (buf && len >= 6) {
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
tuple.DesiredTuple = 0x88;
|
|
||||||
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
|
|
||||||
pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
phys_addr[i] = htons(le16_to_cpu(buf[i]));
|
phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
|
||||||
|
kfree(buf);
|
||||||
} else {
|
} else {
|
||||||
|
kfree(buf); /* 0 < len < 6 */
|
||||||
EL3WINDOW(0);
|
EL3WINDOW(0);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
|
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
|
||||||
@ -435,7 +424,8 @@ static int tc574_config(struct pcmcia_device *link)
|
|||||||
mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
|
mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
|
||||||
if (mii_status != 0xffff) {
|
if (mii_status != 0xffff) {
|
||||||
lp->phys = phy & 0x1f;
|
lp->phys = phy & 0x1f;
|
||||||
DEBUG(0, " MII transceiver at index %d, status %x.\n",
|
dev_dbg(&link->dev, " MII transceiver at "
|
||||||
|
"index %d, status %x.\n",
|
||||||
phy, mii_status);
|
phy, mii_status);
|
||||||
if ((mii_status & 0x0040) == 0)
|
if ((mii_status & 0x0040) == 0)
|
||||||
mii_preamble_required = 1;
|
mii_preamble_required = 1;
|
||||||
@ -457,7 +447,7 @@ static int tc574_config(struct pcmcia_device *link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
link->dev_node = &lp->node;
|
link->dev_node = &lp->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if (register_netdev(dev) != 0) {
|
if (register_netdev(dev) != 0) {
|
||||||
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
|
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
|
||||||
@ -478,8 +468,6 @@ static int tc574_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
tc574_release(link);
|
tc574_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -738,7 +726,7 @@ static int el3_open(struct net_device *dev)
|
|||||||
lp->media.expires = jiffies + HZ;
|
lp->media.expires = jiffies + HZ;
|
||||||
add_timer(&lp->media);
|
add_timer(&lp->media);
|
||||||
|
|
||||||
DEBUG(2, "%s: opened, status %4.4x.\n",
|
dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
|
||||||
dev->name, inw(dev->base_addr + EL3_STATUS));
|
dev->name, inw(dev->base_addr + EL3_STATUS));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -772,7 +760,7 @@ static void pop_tx_status(struct net_device *dev)
|
|||||||
if (tx_status & 0x30)
|
if (tx_status & 0x30)
|
||||||
tc574_wait_for_completion(dev, TxReset);
|
tc574_wait_for_completion(dev, TxReset);
|
||||||
if (tx_status & 0x38) {
|
if (tx_status & 0x38) {
|
||||||
DEBUG(1, "%s: transmit error: status 0x%02x\n",
|
pr_debug("%s: transmit error: status 0x%02x\n",
|
||||||
dev->name, tx_status);
|
dev->name, tx_status);
|
||||||
outw(TxEnable, ioaddr + EL3_CMD);
|
outw(TxEnable, ioaddr + EL3_CMD);
|
||||||
dev->stats.tx_aborted_errors++;
|
dev->stats.tx_aborted_errors++;
|
||||||
@ -788,7 +776,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
|
|||||||
struct el3_private *lp = netdev_priv(dev);
|
struct el3_private *lp = netdev_priv(dev);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
|
pr_debug("%s: el3_start_xmit(length = %ld) called, "
|
||||||
"status %4.4x.\n", dev->name, (long)skb->len,
|
"status %4.4x.\n", dev->name, (long)skb->len,
|
||||||
inw(ioaddr + EL3_STATUS));
|
inw(ioaddr + EL3_STATUS));
|
||||||
|
|
||||||
@ -827,7 +815,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
ioaddr = dev->base_addr;
|
ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(3, "%s: interrupt, status %4.4x.\n",
|
pr_debug("%s: interrupt, status %4.4x.\n",
|
||||||
dev->name, inw(ioaddr + EL3_STATUS));
|
dev->name, inw(ioaddr + EL3_STATUS));
|
||||||
|
|
||||||
spin_lock(&lp->window_lock);
|
spin_lock(&lp->window_lock);
|
||||||
@ -836,7 +824,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
(IntLatch | RxComplete | RxEarly | StatsFull)) {
|
(IntLatch | RxComplete | RxEarly | StatsFull)) {
|
||||||
if (!netif_device_present(dev) ||
|
if (!netif_device_present(dev) ||
|
||||||
((status & 0xe000) != 0x2000)) {
|
((status & 0xe000) != 0x2000)) {
|
||||||
DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
|
pr_debug("%s: Interrupt from dead card\n", dev->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,7 +834,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
work_budget = el3_rx(dev, work_budget);
|
work_budget = el3_rx(dev, work_budget);
|
||||||
|
|
||||||
if (status & TxAvailable) {
|
if (status & TxAvailable) {
|
||||||
DEBUG(3, " TX room bit was handled.\n");
|
pr_debug(" TX room bit was handled.\n");
|
||||||
/* There's room in the FIFO for a full-sized packet. */
|
/* There's room in the FIFO for a full-sized packet. */
|
||||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
@ -886,7 +874,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (--work_budget < 0) {
|
if (--work_budget < 0) {
|
||||||
DEBUG(0, "%s: Too much work in interrupt, "
|
pr_debug("%s: Too much work in interrupt, "
|
||||||
"status %4.4x.\n", dev->name, status);
|
"status %4.4x.\n", dev->name, status);
|
||||||
/* Clear all interrupts */
|
/* Clear all interrupts */
|
||||||
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
|
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
|
||||||
@ -896,7 +884,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
|
outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
|
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||||
dev->name, inw(ioaddr + EL3_STATUS));
|
dev->name, inw(ioaddr + EL3_STATUS));
|
||||||
|
|
||||||
spin_unlock(&lp->window_lock);
|
spin_unlock(&lp->window_lock);
|
||||||
@ -1003,7 +991,7 @@ static void update_stats(struct net_device *dev)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
u8 rx, tx, up;
|
u8 rx, tx, up;
|
||||||
|
|
||||||
DEBUG(2, "%s: updating the statistics.\n", dev->name);
|
pr_debug("%s: updating the statistics.\n", dev->name);
|
||||||
|
|
||||||
if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
|
if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
|
||||||
return;
|
return;
|
||||||
@ -1039,7 +1027,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
short rx_status;
|
short rx_status;
|
||||||
|
|
||||||
DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||||
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
|
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
|
||||||
while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
|
while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
|
||||||
worklimit > 0) {
|
worklimit > 0) {
|
||||||
@ -1061,7 +1049,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
|
|||||||
|
|
||||||
skb = dev_alloc_skb(pkt_len+5);
|
skb = dev_alloc_skb(pkt_len+5);
|
||||||
|
|
||||||
DEBUG(3, " Receiving packet size %d status %4.4x.\n",
|
pr_debug(" Receiving packet size %d status %4.4x.\n",
|
||||||
pkt_len, rx_status);
|
pkt_len, rx_status);
|
||||||
if (skb != NULL) {
|
if (skb != NULL) {
|
||||||
skb_reserve(skb, 2);
|
skb_reserve(skb, 2);
|
||||||
@ -1072,7 +1060,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
|
|||||||
dev->stats.rx_packets++;
|
dev->stats.rx_packets++;
|
||||||
dev->stats.rx_bytes += pkt_len;
|
dev->stats.rx_bytes += pkt_len;
|
||||||
} else {
|
} else {
|
||||||
DEBUG(1, "%s: couldn't allocate a sk_buff of"
|
pr_debug("%s: couldn't allocate a sk_buff of"
|
||||||
" size %d.\n", dev->name, pkt_len);
|
" size %d.\n", dev->name, pkt_len);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
@ -1101,7 +1089,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||||||
struct mii_ioctl_data *data = if_mii(rq);
|
struct mii_ioctl_data *data = if_mii(rq);
|
||||||
int phy = lp->phys & 0x1f;
|
int phy = lp->phys & 0x1f;
|
||||||
|
|
||||||
DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
|
pr_debug("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
|
||||||
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
|
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
|
||||||
data->phy_id, data->reg_num, data->val_in, data->val_out);
|
data->phy_id, data->reg_num, data->val_in, data->val_out);
|
||||||
|
|
||||||
@ -1178,7 +1166,7 @@ static int el3_close(struct net_device *dev)
|
|||||||
struct el3_private *lp = netdev_priv(dev);
|
struct el3_private *lp = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = lp->p_dev;
|
struct pcmcia_device *link = lp->p_dev;
|
||||||
|
|
||||||
DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
|
dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
|
||||||
|
|
||||||
if (pcmcia_dev_present(link)) {
|
if (pcmcia_dev_present(link)) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -130,14 +130,6 @@ MODULE_LICENSE("GPL");
|
|||||||
/* Special hook for setting if_port when module is loaded */
|
/* Special hook for setting if_port when module is loaded */
|
||||||
INT_MODULE_PARM(if_port, 0);
|
INT_MODULE_PARM(if_port, 0);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -189,7 +181,7 @@ static int tc589_probe(struct pcmcia_device *link)
|
|||||||
struct el3_private *lp;
|
struct el3_private *lp;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
DEBUG(0, "3c589_attach()\n");
|
dev_dbg(&link->dev, "3c589_attach()\n");
|
||||||
|
|
||||||
/* Create new ethernet device */
|
/* Create new ethernet device */
|
||||||
dev = alloc_etherdev(sizeof(struct el3_private));
|
dev = alloc_etherdev(sizeof(struct el3_private));
|
||||||
@ -202,10 +194,8 @@ static int tc589_probe(struct pcmcia_device *link)
|
|||||||
spin_lock_init(&lp->lock);
|
spin_lock_init(&lp->lock);
|
||||||
link->io.NumPorts1 = 16;
|
link->io.NumPorts1 = 16;
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = &el3_interrupt;
|
link->irq.Handler = &el3_interrupt;
|
||||||
link->irq.Instance = dev;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.ConfigIndex = 1;
|
link->conf.ConfigIndex = 1;
|
||||||
@ -231,7 +221,7 @@ static void tc589_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "3c589_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "3c589_detach\n");
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -249,29 +239,20 @@ static void tc589_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int tc589_config(struct pcmcia_device *link)
|
static int tc589_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
struct el3_private *lp = netdev_priv(dev);
|
struct el3_private *lp = netdev_priv(dev);
|
||||||
tuple_t tuple;
|
|
||||||
__le16 buf[32];
|
|
||||||
__be16 *phys_addr;
|
__be16 *phys_addr;
|
||||||
int last_fn, last_ret, i, j, multi = 0, fifo;
|
int ret, i, j, multi = 0, fifo;
|
||||||
unsigned int ioaddr;
|
unsigned int ioaddr;
|
||||||
char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
|
char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
|
||||||
|
u8 *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
DEBUG(0, "3c589_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "3c589_config\n");
|
||||||
|
|
||||||
phys_addr = (__be16 *)dev->dev_addr;
|
phys_addr = (__be16 *)dev->dev_addr;
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = (cisdata_t *)buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
|
||||||
|
|
||||||
/* Is this a 3c562? */
|
/* Is this a 3c562? */
|
||||||
if (link->manf_id != MANFID_3COM)
|
if (link->manf_id != MANFID_3COM)
|
||||||
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
|
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
|
||||||
@ -287,12 +268,16 @@ static int tc589_config(struct pcmcia_device *link)
|
|||||||
if (i == 0)
|
if (i == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIO, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
@ -301,12 +286,13 @@ static int tc589_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* The 3c589 has an extra EEPROM for configuration info, including
|
/* The 3c589 has an extra EEPROM for configuration info, including
|
||||||
the hardware address. The 3c562 puts the address in the CIS. */
|
the hardware address. The 3c562 puts the address in the CIS. */
|
||||||
tuple.DesiredTuple = 0x88;
|
len = pcmcia_get_tuple(link, 0x88, &buf);
|
||||||
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
|
if (buf && len >= 6) {
|
||||||
pcmcia_get_tuple_data(link, &tuple);
|
for (i = 0; i < 3; i++)
|
||||||
for (i = 0; i < 3; i++)
|
phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
|
||||||
phys_addr[i] = htons(le16_to_cpu(buf[i]));
|
kfree(buf);
|
||||||
} else {
|
} else {
|
||||||
|
kfree(buf); /* 0 < len < 6 */
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
phys_addr[i] = htons(read_eeprom(ioaddr, i));
|
phys_addr[i] = htons(read_eeprom(ioaddr, i));
|
||||||
if (phys_addr[0] == htons(0x6060)) {
|
if (phys_addr[0] == htons(0x6060)) {
|
||||||
@ -328,7 +314,7 @@ static int tc589_config(struct pcmcia_device *link)
|
|||||||
printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
|
printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
|
||||||
|
|
||||||
link->dev_node = &lp->node;
|
link->dev_node = &lp->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if (register_netdev(dev) != 0) {
|
if (register_netdev(dev) != 0) {
|
||||||
printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
|
printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
|
||||||
@ -347,8 +333,6 @@ static int tc589_config(struct pcmcia_device *link)
|
|||||||
if_names[dev->if_port]);
|
if_names[dev->if_port]);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
tc589_release(link);
|
tc589_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -511,24 +495,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
|
|||||||
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static u32 netdev_get_msglevel(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return pc_debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void netdev_set_msglevel(struct net_device *dev, u32 level)
|
|
||||||
{
|
|
||||||
pc_debug = level;
|
|
||||||
}
|
|
||||||
#endif /* PCMCIA_DEBUG */
|
|
||||||
|
|
||||||
static const struct ethtool_ops netdev_ethtool_ops = {
|
static const struct ethtool_ops netdev_ethtool_ops = {
|
||||||
.get_drvinfo = netdev_get_drvinfo,
|
.get_drvinfo = netdev_get_drvinfo,
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
.get_msglevel = netdev_get_msglevel,
|
|
||||||
.set_msglevel = netdev_set_msglevel,
|
|
||||||
#endif /* PCMCIA_DEBUG */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int el3_config(struct net_device *dev, struct ifmap *map)
|
static int el3_config(struct net_device *dev, struct ifmap *map)
|
||||||
@ -563,7 +531,7 @@ static int el3_open(struct net_device *dev)
|
|||||||
lp->media.expires = jiffies + HZ;
|
lp->media.expires = jiffies + HZ;
|
||||||
add_timer(&lp->media);
|
add_timer(&lp->media);
|
||||||
|
|
||||||
DEBUG(1, "%s: opened, status %4.4x.\n",
|
dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
|
||||||
dev->name, inw(dev->base_addr + EL3_STATUS));
|
dev->name, inw(dev->base_addr + EL3_STATUS));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -596,7 +564,7 @@ static void pop_tx_status(struct net_device *dev)
|
|||||||
if (tx_status & 0x30)
|
if (tx_status & 0x30)
|
||||||
tc589_wait_for_completion(dev, TxReset);
|
tc589_wait_for_completion(dev, TxReset);
|
||||||
if (tx_status & 0x38) {
|
if (tx_status & 0x38) {
|
||||||
DEBUG(1, "%s: transmit error: status 0x%02x\n",
|
pr_debug("%s: transmit error: status 0x%02x\n",
|
||||||
dev->name, tx_status);
|
dev->name, tx_status);
|
||||||
outw(TxEnable, ioaddr + EL3_CMD);
|
outw(TxEnable, ioaddr + EL3_CMD);
|
||||||
dev->stats.tx_aborted_errors++;
|
dev->stats.tx_aborted_errors++;
|
||||||
@ -612,7 +580,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
|
|||||||
struct el3_private *priv = netdev_priv(dev);
|
struct el3_private *priv = netdev_priv(dev);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
|
pr_debug("%s: el3_start_xmit(length = %ld) called, "
|
||||||
"status %4.4x.\n", dev->name, (long)skb->len,
|
"status %4.4x.\n", dev->name, (long)skb->len,
|
||||||
inw(ioaddr + EL3_STATUS));
|
inw(ioaddr + EL3_STATUS));
|
||||||
|
|
||||||
@ -654,14 +622,14 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
|
|
||||||
ioaddr = dev->base_addr;
|
ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(3, "%s: interrupt, status %4.4x.\n",
|
pr_debug("%s: interrupt, status %4.4x.\n",
|
||||||
dev->name, inw(ioaddr + EL3_STATUS));
|
dev->name, inw(ioaddr + EL3_STATUS));
|
||||||
|
|
||||||
spin_lock(&lp->lock);
|
spin_lock(&lp->lock);
|
||||||
while ((status = inw(ioaddr + EL3_STATUS)) &
|
while ((status = inw(ioaddr + EL3_STATUS)) &
|
||||||
(IntLatch | RxComplete | StatsFull)) {
|
(IntLatch | RxComplete | StatsFull)) {
|
||||||
if ((status & 0xe000) != 0x2000) {
|
if ((status & 0xe000) != 0x2000) {
|
||||||
DEBUG(1, "%s: interrupt from dead card\n", dev->name);
|
pr_debug("%s: interrupt from dead card\n", dev->name);
|
||||||
handled = 0;
|
handled = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -670,7 +638,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
el3_rx(dev);
|
el3_rx(dev);
|
||||||
|
|
||||||
if (status & TxAvailable) {
|
if (status & TxAvailable) {
|
||||||
DEBUG(3, " TX room bit was handled.\n");
|
pr_debug(" TX room bit was handled.\n");
|
||||||
/* There's room in the FIFO for a full-sized packet. */
|
/* There's room in the FIFO for a full-sized packet. */
|
||||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
@ -722,7 +690,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||||||
|
|
||||||
lp->last_irq = jiffies;
|
lp->last_irq = jiffies;
|
||||||
spin_unlock(&lp->lock);
|
spin_unlock(&lp->lock);
|
||||||
DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
|
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||||
dev->name, inw(ioaddr + EL3_STATUS));
|
dev->name, inw(ioaddr + EL3_STATUS));
|
||||||
return IRQ_RETVAL(handled);
|
return IRQ_RETVAL(handled);
|
||||||
}
|
}
|
||||||
@ -833,7 +801,7 @@ static void update_stats(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(2, "%s: updating the statistics.\n", dev->name);
|
pr_debug("%s: updating the statistics.\n", dev->name);
|
||||||
/* Turn off statistics updates while reading. */
|
/* Turn off statistics updates while reading. */
|
||||||
outw(StatsDisable, ioaddr + EL3_CMD);
|
outw(StatsDisable, ioaddr + EL3_CMD);
|
||||||
/* Switch to the stats window, and read everything. */
|
/* Switch to the stats window, and read everything. */
|
||||||
@ -861,7 +829,7 @@ static int el3_rx(struct net_device *dev)
|
|||||||
int worklimit = 32;
|
int worklimit = 32;
|
||||||
short rx_status;
|
short rx_status;
|
||||||
|
|
||||||
DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||||
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
|
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
|
||||||
while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
|
while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
|
||||||
worklimit > 0) {
|
worklimit > 0) {
|
||||||
@ -883,7 +851,7 @@ static int el3_rx(struct net_device *dev)
|
|||||||
|
|
||||||
skb = dev_alloc_skb(pkt_len+5);
|
skb = dev_alloc_skb(pkt_len+5);
|
||||||
|
|
||||||
DEBUG(3, " Receiving packet size %d status %4.4x.\n",
|
pr_debug(" Receiving packet size %d status %4.4x.\n",
|
||||||
pkt_len, rx_status);
|
pkt_len, rx_status);
|
||||||
if (skb != NULL) {
|
if (skb != NULL) {
|
||||||
skb_reserve(skb, 2);
|
skb_reserve(skb, 2);
|
||||||
@ -894,7 +862,7 @@ static int el3_rx(struct net_device *dev)
|
|||||||
dev->stats.rx_packets++;
|
dev->stats.rx_packets++;
|
||||||
dev->stats.rx_bytes += pkt_len;
|
dev->stats.rx_bytes += pkt_len;
|
||||||
} else {
|
} else {
|
||||||
DEBUG(1, "%s: couldn't allocate a sk_buff of"
|
pr_debug("%s: couldn't allocate a sk_buff of"
|
||||||
" size %d.\n", dev->name, pkt_len);
|
" size %d.\n", dev->name, pkt_len);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
@ -935,7 +903,7 @@ static int el3_close(struct net_device *dev)
|
|||||||
struct pcmcia_device *link = lp->p_dev;
|
struct pcmcia_device *link = lp->p_dev;
|
||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
|
dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
|
||||||
|
|
||||||
if (pcmcia_dev_present(link)) {
|
if (pcmcia_dev_present(link)) {
|
||||||
/* Turn off statistics ASAP. We update dev->stats below. */
|
/* Turn off statistics ASAP. We update dev->stats below. */
|
||||||
|
@ -75,16 +75,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
|||||||
MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
|
MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
|
|
||||||
|
|
||||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"axnet_cs.c 1.28 2002/06/29 06:27:37 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -167,7 +157,7 @@ static int axnet_probe(struct pcmcia_device *link)
|
|||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct ei_device *ei_local;
|
struct ei_device *ei_local;
|
||||||
|
|
||||||
DEBUG(0, "axnet_attach()\n");
|
dev_dbg(&link->dev, "axnet_attach()\n");
|
||||||
|
|
||||||
dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
|
dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
|
||||||
if (!dev)
|
if (!dev)
|
||||||
@ -180,7 +170,6 @@ static int axnet_probe(struct pcmcia_device *link)
|
|||||||
info->p_dev = link;
|
info->p_dev = link;
|
||||||
link->priv = dev;
|
link->priv = dev;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -205,7 +194,7 @@ static void axnet_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "axnet_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -272,9 +261,6 @@ static int get_prom(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int try_io_port(struct pcmcia_device *link)
|
static int try_io_port(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
int j, ret;
|
int j, ret;
|
||||||
@ -341,26 +327,29 @@ static int axnet_config(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
axnet_dev_t *info = PRIV(dev);
|
axnet_dev_t *info = PRIV(dev);
|
||||||
int i, j, j2, last_ret, last_fn;
|
int i, j, j2, ret;
|
||||||
|
|
||||||
DEBUG(0, "axnet_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "axnet_config(0x%p)\n", link);
|
||||||
|
|
||||||
/* don't trust the CIS on this; Linksys got it wrong */
|
/* don't trust the CIS on this; Linksys got it wrong */
|
||||||
link->conf.Present = 0x63;
|
link->conf.Present = 0x63;
|
||||||
last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
|
ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
|
||||||
if (last_ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
if (link->io.NumPorts2 == 8) {
|
if (link->io.NumPorts2 == 8) {
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
link->conf.Status = CCSR_AUDIO_ENA;
|
||||||
}
|
}
|
||||||
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
|
|
||||||
@ -410,7 +399,7 @@ static int axnet_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
info->phy_id = (i < 32) ? i : -1;
|
info->phy_id = (i < 32) ? i : -1;
|
||||||
link->dev_node = &info->node;
|
link->dev_node = &info->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if (register_netdev(dev) != 0) {
|
if (register_netdev(dev) != 0) {
|
||||||
printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
|
printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
|
||||||
@ -426,14 +415,12 @@ static int axnet_config(struct pcmcia_device *link)
|
|||||||
dev->base_addr, dev->irq,
|
dev->base_addr, dev->irq,
|
||||||
dev->dev_addr);
|
dev->dev_addr);
|
||||||
if (info->phy_id != -1) {
|
if (info->phy_id != -1) {
|
||||||
DEBUG(0, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
|
dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_NOTICE " No MII transceivers found!\n");
|
printk(KERN_NOTICE " No MII transceivers found!\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
axnet_release(link);
|
axnet_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -543,7 +530,7 @@ static int axnet_open(struct net_device *dev)
|
|||||||
struct pcmcia_device *link = info->p_dev;
|
struct pcmcia_device *link = info->p_dev;
|
||||||
unsigned int nic_base = dev->base_addr;
|
unsigned int nic_base = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(2, "axnet_open('%s')\n", dev->name);
|
dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name);
|
||||||
|
|
||||||
if (!pcmcia_dev_present(link))
|
if (!pcmcia_dev_present(link))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -572,7 +559,7 @@ static int axnet_close(struct net_device *dev)
|
|||||||
axnet_dev_t *info = PRIV(dev);
|
axnet_dev_t *info = PRIV(dev);
|
||||||
struct pcmcia_device *link = info->p_dev;
|
struct pcmcia_device *link = info->p_dev;
|
||||||
|
|
||||||
DEBUG(2, "axnet_close('%s')\n", dev->name);
|
dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name);
|
||||||
|
|
||||||
ax_close(dev);
|
ax_close(dev);
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
@ -741,10 +728,8 @@ static void block_input(struct net_device *dev, int count,
|
|||||||
int xfer_count = count;
|
int xfer_count = count;
|
||||||
char *buf = skb->data;
|
char *buf = skb->data;
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
if ((ei_debug > 4) && (count != 4))
|
if ((ei_debug > 4) && (count != 4))
|
||||||
printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
|
pr_debug("%s: [bi=%d]\n", dev->name, count+4);
|
||||||
#endif
|
|
||||||
outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
|
outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
|
||||||
outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
|
outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
|
||||||
outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD);
|
outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD);
|
||||||
@ -762,10 +747,7 @@ static void block_output(struct net_device *dev, int count,
|
|||||||
{
|
{
|
||||||
unsigned int nic_base = dev->base_addr;
|
unsigned int nic_base = dev->base_addr;
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
pr_debug("%s: [bo=%d]\n", dev->name, count);
|
||||||
if (ei_debug > 4)
|
|
||||||
printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Round the count up for word writes. Do we need to do this?
|
/* Round the count up for word writes. Do we need to do this?
|
||||||
What effect will an odd byte count have on the 8390?
|
What effect will an odd byte count have on the 8390?
|
||||||
|
@ -53,11 +53,7 @@
|
|||||||
|
|
||||||
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
|
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
|
|
||||||
static void regdump(struct net_device *dev)
|
static void regdump(struct net_device *dev)
|
||||||
{
|
{
|
||||||
@ -92,7 +88,6 @@ static void regdump(struct net_device *dev)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define DEBUG(n, args...) do { } while (0)
|
|
||||||
static inline void regdump(struct net_device *dev) { }
|
static inline void regdump(struct net_device *dev) { }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -144,7 +139,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
|
|||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct arcnet_local *lp;
|
struct arcnet_local *lp;
|
||||||
|
|
||||||
DEBUG(0, "com20020_attach()\n");
|
dev_dbg(&p_dev->dev, "com20020_attach()\n");
|
||||||
|
|
||||||
/* Create new network device */
|
/* Create new network device */
|
||||||
info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
|
info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
|
||||||
@ -169,11 +164,10 @@ static int com20020_probe(struct pcmcia_device *p_dev)
|
|||||||
p_dev->io.NumPorts1 = 16;
|
p_dev->io.NumPorts1 = 16;
|
||||||
p_dev->io.IOAddrLines = 16;
|
p_dev->io.IOAddrLines = 16;
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
p_dev->irq.Instance = info->dev = dev;
|
info->dev = dev;
|
||||||
p_dev->priv = info;
|
p_dev->priv = info;
|
||||||
|
|
||||||
return com20020_config(p_dev);
|
return com20020_config(p_dev);
|
||||||
@ -198,12 +192,12 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||||||
struct com20020_dev_t *info = link->priv;
|
struct com20020_dev_t *info = link->priv;
|
||||||
struct net_device *dev = info->dev;
|
struct net_device *dev = info->dev;
|
||||||
|
|
||||||
DEBUG(1,"detach...\n");
|
dev_dbg(&link->dev, "detach...\n");
|
||||||
|
|
||||||
DEBUG(0, "com20020_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "com20020_detach\n");
|
||||||
|
|
||||||
if (link->dev_node) {
|
if (link->dev_node) {
|
||||||
DEBUG(1,"unregister...\n");
|
dev_dbg(&link->dev, "unregister...\n");
|
||||||
|
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
|
|
||||||
@ -218,16 +212,16 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||||||
com20020_release(link);
|
com20020_release(link);
|
||||||
|
|
||||||
/* Unlink device structure, free bits */
|
/* Unlink device structure, free bits */
|
||||||
DEBUG(1,"unlinking...\n");
|
dev_dbg(&link->dev, "unlinking...\n");
|
||||||
if (link->priv)
|
if (link->priv)
|
||||||
{
|
{
|
||||||
dev = info->dev;
|
dev = info->dev;
|
||||||
if (dev)
|
if (dev)
|
||||||
{
|
{
|
||||||
DEBUG(1,"kfree...\n");
|
dev_dbg(&link->dev, "kfree...\n");
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
}
|
}
|
||||||
DEBUG(1,"kfree2...\n");
|
dev_dbg(&link->dev, "kfree2...\n");
|
||||||
kfree(info);
|
kfree(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,25 +235,22 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int com20020_config(struct pcmcia_device *link)
|
static int com20020_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct arcnet_local *lp;
|
struct arcnet_local *lp;
|
||||||
com20020_dev_t *info;
|
com20020_dev_t *info;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
int i, last_ret, last_fn;
|
int i, ret;
|
||||||
int ioaddr;
|
int ioaddr;
|
||||||
|
|
||||||
info = link->priv;
|
info = link->priv;
|
||||||
dev = info->dev;
|
dev = info->dev;
|
||||||
|
|
||||||
DEBUG(1,"config...\n");
|
dev_dbg(&link->dev, "config...\n");
|
||||||
|
|
||||||
DEBUG(0, "com20020_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "com20020_config\n");
|
||||||
|
|
||||||
DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
|
dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
|
||||||
i = -ENODEV;
|
i = -ENODEV;
|
||||||
if (!link->io.BasePort1)
|
if (!link->io.BasePort1)
|
||||||
{
|
{
|
||||||
@ -276,26 +267,27 @@ static int com20020_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
DEBUG(1,"arcnet: requestIO failed totally!\n");
|
dev_dbg(&link->dev, "requestIO failed totally!\n");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ioaddr = dev->base_addr = link->io.BasePort1;
|
ioaddr = dev->base_addr = link->io.BasePort1;
|
||||||
DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);
|
dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
|
||||||
|
|
||||||
DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
|
dev_dbg(&link->dev, "request IRQ %d\n",
|
||||||
link->irq.AssignedIRQ,
|
link->irq.AssignedIRQ);
|
||||||
link->irq.IRQInfo1, link->irq.IRQInfo2);
|
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
DEBUG(1,"arcnet: requestIRQ failed totally!\n");
|
dev_dbg(&link->dev, "requestIRQ failed totally!\n");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
if (com20020_check(dev))
|
if (com20020_check(dev))
|
||||||
{
|
{
|
||||||
@ -308,26 +300,25 @@ static int com20020_config(struct pcmcia_device *link)
|
|||||||
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
|
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
|
||||||
|
|
||||||
link->dev_node = &info->node;
|
link->dev_node = &info->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
i = com20020_found(dev, 0); /* calls register_netdev */
|
i = com20020_found(dev, 0); /* calls register_netdev */
|
||||||
|
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
|
dev_printk(KERN_NOTICE, &link->dev,
|
||||||
|
"com20020_cs: com20020_found() failed\n");
|
||||||
link->dev_node = NULL;
|
link->dev_node = NULL;
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(info->node.dev_name, dev->name);
|
strcpy(info->node.dev_name, dev->name);
|
||||||
|
|
||||||
DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
|
dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
|
||||||
dev->name, dev->base_addr, dev->irq);
|
dev->name, dev->base_addr, dev->irq);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
DEBUG(1,"com20020_config failed...\n");
|
dev_dbg(&link->dev, "com20020_config failed...\n");
|
||||||
com20020_release(link);
|
com20020_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} /* com20020_config */
|
} /* com20020_config */
|
||||||
@ -342,7 +333,7 @@ static int com20020_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void com20020_release(struct pcmcia_device *link)
|
static void com20020_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "com20020_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "com20020_release\n");
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,13 +72,6 @@ MODULE_LICENSE("GPL");
|
|||||||
/* 0:4KB*2 TX buffer else:8KB*2 TX buffer */
|
/* 0:4KB*2 TX buffer else:8KB*2 TX buffer */
|
||||||
INT_MODULE_PARM(sram_config, 0);
|
INT_MODULE_PARM(sram_config, 0);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
/*
|
/*
|
||||||
@ -245,7 +238,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
|
|||||||
local_info_t *lp;
|
local_info_t *lp;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
DEBUG(0, "fmvj18x_attach()\n");
|
dev_dbg(&link->dev, "fmvj18x_attach()\n");
|
||||||
|
|
||||||
/* Make up a FMVJ18x specific data structure */
|
/* Make up a FMVJ18x specific data structure */
|
||||||
dev = alloc_etherdev(sizeof(local_info_t));
|
dev = alloc_etherdev(sizeof(local_info_t));
|
||||||
@ -262,10 +255,8 @@ static int fmvj18x_probe(struct pcmcia_device *link)
|
|||||||
link->io.IOAddrLines = 5;
|
link->io.IOAddrLines = 5;
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = &fjn_interrupt;
|
link->irq.Handler = &fjn_interrupt;
|
||||||
link->irq.Instance = dev;
|
|
||||||
|
|
||||||
/* General socket configuration */
|
/* General socket configuration */
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
@ -285,7 +276,7 @@ static void fmvj18x_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "fmvj18x_detach\n");
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -297,9 +288,6 @@ static void fmvj18x_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int mfc_try_io_port(struct pcmcia_device *link)
|
static int mfc_try_io_port(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
@ -341,33 +329,38 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
|
|||||||
return ret; /* RequestIO failed */
|
return ret; /* RequestIO failed */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
return 0; /* strange, but that's what the code did already before... */
|
||||||
|
}
|
||||||
|
|
||||||
static int fmvj18x_config(struct pcmcia_device *link)
|
static int fmvj18x_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
local_info_t *lp = netdev_priv(dev);
|
local_info_t *lp = netdev_priv(dev);
|
||||||
tuple_t tuple;
|
int i, ret;
|
||||||
cisparse_t parse;
|
|
||||||
u_short buf[32];
|
|
||||||
int i, last_fn = 0, last_ret = 0, ret;
|
|
||||||
unsigned int ioaddr;
|
unsigned int ioaddr;
|
||||||
cardtype_t cardtype;
|
cardtype_t cardtype;
|
||||||
char *card_name = "unknown";
|
char *card_name = "unknown";
|
||||||
u_char *node_id;
|
u8 *buf;
|
||||||
|
size_t len;
|
||||||
|
u_char buggybuf[32];
|
||||||
|
|
||||||
DEBUG(0, "fmvj18x_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "fmvj18x_config\n");
|
||||||
|
|
||||||
tuple.TupleData = (u_char *)buf;
|
len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
|
||||||
tuple.TupleDataMax = 64;
|
kfree(buf);
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
if (len) {
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
|
|
||||||
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
|
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
|
||||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
if (ret != 0)
|
||||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
goto failed;
|
||||||
CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
|
|
||||||
link->conf.ConfigIndex = parse.cftable_entry.index;
|
|
||||||
switch (link->manf_id) {
|
switch (link->manf_id) {
|
||||||
case MANFID_TDK:
|
case MANFID_TDK:
|
||||||
cardtype = TDK;
|
cardtype = TDK;
|
||||||
@ -433,17 +426,24 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
if (link->io.NumPorts2 != 0) {
|
if (link->io.NumPorts2 != 0) {
|
||||||
link->irq.Attributes =
|
link->irq.Attributes =
|
||||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
|
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
ret = mfc_try_io_port(link);
|
ret = mfc_try_io_port(link);
|
||||||
if (ret != 0) goto cs_failed;
|
if (ret != 0) goto failed;
|
||||||
} else if (cardtype == UNGERMANN) {
|
} else if (cardtype == UNGERMANN) {
|
||||||
ret = ungermann_try_io_port(link);
|
ret = ungermann_try_io_port(link);
|
||||||
if (ret != 0) goto cs_failed;
|
if (ret != 0) goto failed;
|
||||||
} else {
|
} else {
|
||||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
ret = pcmcia_request_io(link, &link->io);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
}
|
}
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
|
|
||||||
@ -474,21 +474,21 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||||||
case CONTEC:
|
case CONTEC:
|
||||||
case NEC:
|
case NEC:
|
||||||
case KME:
|
case KME:
|
||||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
|
||||||
if (cardtype == MBH10304) {
|
if (cardtype == MBH10304) {
|
||||||
/* MBH10304's CIS_FUNCE is corrupted */
|
|
||||||
node_id = &(tuple.TupleData[5]);
|
|
||||||
card_name = "FMV-J182";
|
card_name = "FMV-J182";
|
||||||
} else {
|
|
||||||
while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
|
len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
|
||||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
if (len < 11) {
|
||||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
kfree(buf);
|
||||||
|
goto failed;
|
||||||
}
|
}
|
||||||
node_id = &(tuple.TupleData[2]);
|
/* Read MACID from CIS */
|
||||||
|
for (i = 5; i < 11; i++)
|
||||||
|
dev->dev_addr[i] = buf[i];
|
||||||
|
kfree(buf);
|
||||||
|
} else {
|
||||||
|
if (pcmcia_get_mac_from_cis(link, dev))
|
||||||
|
goto failed;
|
||||||
if( cardtype == TDK ) {
|
if( cardtype == TDK ) {
|
||||||
card_name = "TDK LAK-CD021";
|
card_name = "TDK LAK-CD021";
|
||||||
} else if( cardtype == LA501 ) {
|
} else if( cardtype == LA501 ) {
|
||||||
@ -501,9 +501,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||||||
card_name = "C-NET(PC)C";
|
card_name = "C-NET(PC)C";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Read MACID from CIS */
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
dev->dev_addr[i] = node_id[i];
|
|
||||||
break;
|
break;
|
||||||
case UNGERMANN:
|
case UNGERMANN:
|
||||||
/* Read MACID from register */
|
/* Read MACID from register */
|
||||||
@ -513,12 +510,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||||||
break;
|
break;
|
||||||
case XXX10304:
|
case XXX10304:
|
||||||
/* Read MACID from Buggy CIS */
|
/* Read MACID from Buggy CIS */
|
||||||
if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
|
if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
|
||||||
printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
|
printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
for (i = 0 ; i < 6; i++) {
|
for (i = 0 ; i < 6; i++) {
|
||||||
dev->dev_addr[i] = tuple.TupleData[i];
|
dev->dev_addr[i] = buggybuf[i];
|
||||||
}
|
}
|
||||||
card_name = "FMV-J182";
|
card_name = "FMV-J182";
|
||||||
break;
|
break;
|
||||||
@ -533,7 +530,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
lp->cardtype = cardtype;
|
lp->cardtype = cardtype;
|
||||||
link->dev_node = &lp->node;
|
link->dev_node = &lp->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if (register_netdev(dev) != 0) {
|
if (register_netdev(dev) != 0) {
|
||||||
printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
|
printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
|
||||||
@ -551,9 +548,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
/* All Card Services errors end up here */
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
fmvj18x_release(link);
|
fmvj18x_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -571,16 +565,14 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
|
|||||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||||
req.Base = 0; req.Size = 0;
|
req.Base = 0; req.Size = 0;
|
||||||
req.AccessSpeed = 0;
|
req.AccessSpeed = 0;
|
||||||
i = pcmcia_request_window(&link, &req, &link->win);
|
i = pcmcia_request_window(link, &req, &link->win);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestWindow, i);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
base = ioremap(req.Base, req.Size);
|
base = ioremap(req.Base, req.Size);
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
mem.CardOffset = 0;
|
mem.CardOffset = 0;
|
||||||
pcmcia_map_mem_page(link->win, &mem);
|
pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
|
* MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
|
||||||
@ -605,9 +597,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
iounmap(base);
|
iounmap(base);
|
||||||
j = pcmcia_release_window(link->win);
|
j = pcmcia_release_window(link, link->win);
|
||||||
if (j != 0)
|
|
||||||
cs_error(link, ReleaseWindow, j);
|
|
||||||
return (i != 0x200) ? 0 : -1;
|
return (i != 0x200) ? 0 : -1;
|
||||||
|
|
||||||
} /* fmvj18x_get_hwinfo */
|
} /* fmvj18x_get_hwinfo */
|
||||||
@ -626,11 +616,9 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
|
|||||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||||
req.Base = 0; req.Size = 0;
|
req.Base = 0; req.Size = 0;
|
||||||
req.AccessSpeed = 0;
|
req.AccessSpeed = 0;
|
||||||
i = pcmcia_request_window(&link, &req, &link->win);
|
i = pcmcia_request_window(link, &req, &link->win);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestWindow, i);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
lp->base = ioremap(req.Base, req.Size);
|
lp->base = ioremap(req.Base, req.Size);
|
||||||
if (lp->base == NULL) {
|
if (lp->base == NULL) {
|
||||||
@ -640,11 +628,10 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
|
|||||||
|
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
mem.CardOffset = 0;
|
mem.CardOffset = 0;
|
||||||
i = pcmcia_map_mem_page(link->win, &mem);
|
i = pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
iounmap(lp->base);
|
iounmap(lp->base);
|
||||||
lp->base = NULL;
|
lp->base = NULL;
|
||||||
cs_error(link, MapMemPage, i);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,15 +658,13 @@ static void fmvj18x_release(struct pcmcia_device *link)
|
|||||||
u_char __iomem *tmp;
|
u_char __iomem *tmp;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "fmvj18x_release\n");
|
||||||
|
|
||||||
if (lp->base != NULL) {
|
if (lp->base != NULL) {
|
||||||
tmp = lp->base;
|
tmp = lp->base;
|
||||||
lp->base = NULL; /* set NULL before iounmap */
|
lp->base = NULL; /* set NULL before iounmap */
|
||||||
iounmap(tmp);
|
iounmap(tmp);
|
||||||
j = pcmcia_release_window(link->win);
|
j = pcmcia_release_window(link, link->win);
|
||||||
if (j != 0)
|
|
||||||
cs_error(link, ReleaseWindow, j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
@ -788,8 +773,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
|
|||||||
outb(tx_stat, ioaddr + TX_STATUS);
|
outb(tx_stat, ioaddr + TX_STATUS);
|
||||||
outb(rx_stat, ioaddr + RX_STATUS);
|
outb(rx_stat, ioaddr + RX_STATUS);
|
||||||
|
|
||||||
DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
|
pr_debug("%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
|
||||||
DEBUG(4, " tx_status %02x.\n", tx_stat);
|
pr_debug(" tx_status %02x.\n", tx_stat);
|
||||||
|
|
||||||
if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
|
if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
|
||||||
/* there is packet(s) in rx buffer */
|
/* there is packet(s) in rx buffer */
|
||||||
@ -809,8 +794,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
|
|||||||
}
|
}
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
DEBUG(4, "%s: exiting interrupt,\n", dev->name);
|
pr_debug("%s: exiting interrupt,\n", dev->name);
|
||||||
DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
|
pr_debug(" tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
|
||||||
|
|
||||||
outb(D_TX_INTR, ioaddr + TX_INTR);
|
outb(D_TX_INTR, ioaddr + TX_INTR);
|
||||||
outb(D_RX_INTR, ioaddr + RX_INTR);
|
outb(D_RX_INTR, ioaddr + RX_INTR);
|
||||||
@ -882,7 +867,7 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
|
|||||||
return NETDEV_TX_BUSY;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
|
pr_debug("%s: Transmitting a packet of length %lu.\n",
|
||||||
dev->name, (unsigned long)skb->len);
|
dev->name, (unsigned long)skb->len);
|
||||||
dev->stats.tx_bytes += skb->len;
|
dev->stats.tx_bytes += skb->len;
|
||||||
|
|
||||||
@ -937,7 +922,7 @@ static void fjn_reset(struct net_device *dev)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
|
pr_debug("fjn_reset(%s) called.\n",dev->name);
|
||||||
|
|
||||||
/* Reset controller */
|
/* Reset controller */
|
||||||
if( sram_config == 0 )
|
if( sram_config == 0 )
|
||||||
@ -1015,13 +1000,13 @@ static void fjn_rx(struct net_device *dev)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
int boguscount = 10; /* 5 -> 10: by agy 19940922 */
|
int boguscount = 10; /* 5 -> 10: by agy 19940922 */
|
||||||
|
|
||||||
DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
|
pr_debug("%s: in rx_packet(), rx_status %02x.\n",
|
||||||
dev->name, inb(ioaddr + RX_STATUS));
|
dev->name, inb(ioaddr + RX_STATUS));
|
||||||
|
|
||||||
while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
|
while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
|
||||||
u_short status = inw(ioaddr + DATAPORT);
|
u_short status = inw(ioaddr + DATAPORT);
|
||||||
|
|
||||||
DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
|
pr_debug("%s: Rxing packet mode %02x status %04x.\n",
|
||||||
dev->name, inb(ioaddr + RX_MODE), status);
|
dev->name, inb(ioaddr + RX_MODE), status);
|
||||||
#ifndef final_version
|
#ifndef final_version
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
@ -1061,16 +1046,14 @@ static void fjn_rx(struct net_device *dev)
|
|||||||
(pkt_len + 1) >> 1);
|
(pkt_len + 1) >> 1);
|
||||||
skb->protocol = eth_type_trans(skb, dev);
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
{
|
||||||
if (pc_debug > 5) {
|
|
||||||
int i;
|
int i;
|
||||||
printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
|
pr_debug("%s: Rxed packet of length %d: ",
|
||||||
dev->name, pkt_len);
|
dev->name, pkt_len);
|
||||||
for (i = 0; i < 14; i++)
|
for (i = 0; i < 14; i++)
|
||||||
printk(" %02x", skb->data[i]);
|
pr_debug(" %02x", skb->data[i]);
|
||||||
printk(".\n");
|
pr_debug(".\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
dev->stats.rx_packets++;
|
dev->stats.rx_packets++;
|
||||||
@ -1094,7 +1077,7 @@ static void fjn_rx(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
DEBUG(5, "%s: Exint Rx packet with mode %02x after "
|
pr_debug("%s: Exint Rx packet with mode %02x after "
|
||||||
"%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
|
"%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -1112,24 +1095,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
|
|||||||
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static u32 netdev_get_msglevel(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return pc_debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void netdev_set_msglevel(struct net_device *dev, u32 level)
|
|
||||||
{
|
|
||||||
pc_debug = level;
|
|
||||||
}
|
|
||||||
#endif /* PCMCIA_DEBUG */
|
|
||||||
|
|
||||||
static const struct ethtool_ops netdev_ethtool_ops = {
|
static const struct ethtool_ops netdev_ethtool_ops = {
|
||||||
.get_drvinfo = netdev_get_drvinfo,
|
.get_drvinfo = netdev_get_drvinfo,
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
.get_msglevel = netdev_get_msglevel,
|
|
||||||
.set_msglevel = netdev_set_msglevel,
|
|
||||||
#endif /* PCMCIA_DEBUG */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fjn_config(struct net_device *dev, struct ifmap *map){
|
static int fjn_config(struct net_device *dev, struct ifmap *map){
|
||||||
@ -1141,7 +1108,7 @@ static int fjn_open(struct net_device *dev)
|
|||||||
struct local_info_t *lp = netdev_priv(dev);
|
struct local_info_t *lp = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = lp->p_dev;
|
struct pcmcia_device *link = lp->p_dev;
|
||||||
|
|
||||||
DEBUG(4, "fjn_open('%s').\n", dev->name);
|
pr_debug("fjn_open('%s').\n", dev->name);
|
||||||
|
|
||||||
if (!pcmcia_dev_present(link))
|
if (!pcmcia_dev_present(link))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -1167,7 +1134,7 @@ static int fjn_close(struct net_device *dev)
|
|||||||
struct pcmcia_device *link = lp->p_dev;
|
struct pcmcia_device *link = lp->p_dev;
|
||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(4, "fjn_close('%s').\n", dev->name);
|
pr_debug("fjn_close('%s').\n", dev->name);
|
||||||
|
|
||||||
lp->open_time = 0;
|
lp->open_time = 0;
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
@ -69,17 +69,6 @@
|
|||||||
#define PCMCIA
|
#define PCMCIA
|
||||||
#include "../tokenring/ibmtr.c"
|
#include "../tokenring/ibmtr.c"
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
|
|
||||||
" 2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n"
|
|
||||||
" 2.4.2 2001/30/28 Midnight (Burt Silverman)\n";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -130,6 +119,12 @@ static const struct ethtool_ops netdev_ethtool_ops = {
|
|||||||
.get_drvinfo = netdev_get_drvinfo,
|
.get_drvinfo = netdev_get_drvinfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
|
||||||
|
ibmtr_dev_t *info = dev_id;
|
||||||
|
struct net_device *dev = info->dev;
|
||||||
|
return tok_interrupt(irq, dev);
|
||||||
|
};
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
|
|
||||||
ibmtr_attach() creates an "instance" of the driver, allocating
|
ibmtr_attach() creates an "instance" of the driver, allocating
|
||||||
@ -143,7 +138,7 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
|
|||||||
ibmtr_dev_t *info;
|
ibmtr_dev_t *info;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
DEBUG(0, "ibmtr_attach()\n");
|
dev_dbg(&link->dev, "ibmtr_attach()\n");
|
||||||
|
|
||||||
/* Create new token-ring device */
|
/* Create new token-ring device */
|
||||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||||
@ -161,14 +156,13 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts1 = 4;
|
link->io.NumPorts1 = 4;
|
||||||
link->io.IOAddrLines = 16;
|
link->io.IOAddrLines = 16;
|
||||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
link->irq.Handler = ibmtr_interrupt;
|
||||||
link->irq.Handler = &tok_interrupt;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.Present = PRESENT_OPTION;
|
link->conf.Present = PRESENT_OPTION;
|
||||||
|
|
||||||
link->irq.Instance = info->dev = dev;
|
info->dev = dev;
|
||||||
|
|
||||||
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
|
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
|
||||||
|
|
||||||
@ -190,7 +184,7 @@ static void ibmtr_detach(struct pcmcia_device *link)
|
|||||||
struct net_device *dev = info->dev;
|
struct net_device *dev = info->dev;
|
||||||
struct tok_info *ti = netdev_priv(dev);
|
struct tok_info *ti = netdev_priv(dev);
|
||||||
|
|
||||||
DEBUG(0, "ibmtr_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "ibmtr_detach\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the card removal interrupt hits tok_interrupt(),
|
* When the card removal interrupt hits tok_interrupt(),
|
||||||
@ -217,9 +211,6 @@ static void ibmtr_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int __devinit ibmtr_config(struct pcmcia_device *link)
|
static int __devinit ibmtr_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
ibmtr_dev_t *info = link->priv;
|
ibmtr_dev_t *info = link->priv;
|
||||||
@ -227,9 +218,9 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||||||
struct tok_info *ti = netdev_priv(dev);
|
struct tok_info *ti = netdev_priv(dev);
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
memreq_t mem;
|
memreq_t mem;
|
||||||
int i, last_ret, last_fn;
|
int i, ret;
|
||||||
|
|
||||||
DEBUG(0, "ibmtr_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "ibmtr_config\n");
|
||||||
|
|
||||||
link->conf.ConfigIndex = 0x61;
|
link->conf.ConfigIndex = 0x61;
|
||||||
|
|
||||||
@ -241,11 +232,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
/* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
|
/* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
|
||||||
link->io.BasePort1 = 0xA24;
|
link->io.BasePort1 = 0xA24;
|
||||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
ret = pcmcia_request_io(link, &link->io);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
}
|
}
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
ti->irq = link->irq.AssignedIRQ;
|
ti->irq = link->irq.AssignedIRQ;
|
||||||
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
|
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
|
||||||
@ -256,11 +251,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||||||
req.Base = 0;
|
req.Base = 0;
|
||||||
req.Size = 0x2000;
|
req.Size = 0x2000;
|
||||||
req.AccessSpeed = 250;
|
req.AccessSpeed = 250;
|
||||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
ret = pcmcia_request_window(link, &req, &link->win);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
mem.CardOffset = mmiobase;
|
mem.CardOffset = mmiobase;
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
|
ret = pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
ti->mmio = ioremap(req.Base, req.Size);
|
ti->mmio = ioremap(req.Base, req.Size);
|
||||||
|
|
||||||
/* Allocate the SRAM memory window */
|
/* Allocate the SRAM memory window */
|
||||||
@ -269,17 +268,23 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||||||
req.Base = 0;
|
req.Base = 0;
|
||||||
req.Size = sramsize * 1024;
|
req.Size = sramsize * 1024;
|
||||||
req.AccessSpeed = 250;
|
req.AccessSpeed = 250;
|
||||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
|
ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
mem.CardOffset = srambase;
|
mem.CardOffset = srambase;
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
|
ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
ti->sram_base = mem.CardOffset >> 12;
|
ti->sram_base = mem.CardOffset >> 12;
|
||||||
ti->sram_virt = ioremap(req.Base, req.Size);
|
ti->sram_virt = ioremap(req.Base, req.Size);
|
||||||
ti->sram_phys = req.Base;
|
ti->sram_phys = req.Base;
|
||||||
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* Set up the Token-Ring Controller Configuration Register and
|
/* Set up the Token-Ring Controller Configuration Register and
|
||||||
turn on the card. Check the "Local Area Network Credit Card
|
turn on the card. Check the "Local Area Network Credit Card
|
||||||
@ -287,7 +292,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||||||
ibmtr_hw_setup(dev, mmiobase);
|
ibmtr_hw_setup(dev, mmiobase);
|
||||||
|
|
||||||
link->dev_node = &info->node;
|
link->dev_node = &info->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
i = ibmtr_probe_card(dev);
|
i = ibmtr_probe_card(dev);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
@ -305,8 +310,6 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||||||
dev->dev_addr);
|
dev->dev_addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
ibmtr_release(link);
|
ibmtr_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -325,12 +328,12 @@ static void ibmtr_release(struct pcmcia_device *link)
|
|||||||
ibmtr_dev_t *info = link->priv;
|
ibmtr_dev_t *info = link->priv;
|
||||||
struct net_device *dev = info->dev;
|
struct net_device *dev = info->dev;
|
||||||
|
|
||||||
DEBUG(0, "ibmtr_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "ibmtr_release\n");
|
||||||
|
|
||||||
if (link->win) {
|
if (link->win) {
|
||||||
struct tok_info *ti = netdev_priv(dev);
|
struct tok_info *ti = netdev_priv(dev);
|
||||||
iounmap(ti->mmio);
|
iounmap(ti->mmio);
|
||||||
pcmcia_release_window(info->sram_win_handle);
|
pcmcia_release_window(link, info->sram_win_handle);
|
||||||
}
|
}
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
}
|
}
|
||||||
|
@ -381,13 +381,6 @@ typedef struct _mace_private {
|
|||||||
Private Global Variables
|
Private Global Variables
|
||||||
---------------------------------------------------------------------------- */
|
---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static char rcsid[] =
|
|
||||||
"nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao";
|
|
||||||
static char *version =
|
|
||||||
DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *if_names[]={
|
static const char *if_names[]={
|
||||||
"Auto", "10baseT", "BNC",
|
"Auto", "10baseT", "BNC",
|
||||||
};
|
};
|
||||||
@ -406,12 +399,6 @@ MODULE_LICENSE("GPL");
|
|||||||
/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
|
/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
|
||||||
INT_MODULE_PARM(if_port, 0);
|
INT_MODULE_PARM(if_port, 0);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
Function Prototypes
|
Function Prototypes
|
||||||
@ -462,8 +449,7 @@ static int nmclan_probe(struct pcmcia_device *link)
|
|||||||
mace_private *lp;
|
mace_private *lp;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
DEBUG(0, "nmclan_attach()\n");
|
dev_dbg(&link->dev, "nmclan_attach()\n");
|
||||||
DEBUG(1, "%s\n", rcsid);
|
|
||||||
|
|
||||||
/* Create new ethernet device */
|
/* Create new ethernet device */
|
||||||
dev = alloc_etherdev(sizeof(mace_private));
|
dev = alloc_etherdev(sizeof(mace_private));
|
||||||
@ -477,10 +463,8 @@ static int nmclan_probe(struct pcmcia_device *link)
|
|||||||
link->io.NumPorts1 = 32;
|
link->io.NumPorts1 = 32;
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
link->io.IOAddrLines = 5;
|
link->io.IOAddrLines = 5;
|
||||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = &mace_interrupt;
|
link->irq.Handler = &mace_interrupt;
|
||||||
link->irq.Instance = dev;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.ConfigIndex = 1;
|
link->conf.ConfigIndex = 1;
|
||||||
@ -507,7 +491,7 @@ static void nmclan_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "nmclan_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "nmclan_detach\n");
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -654,37 +638,40 @@ nmclan_config
|
|||||||
ethernet device available to the system.
|
ethernet device available to the system.
|
||||||
---------------------------------------------------------------------------- */
|
---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int nmclan_config(struct pcmcia_device *link)
|
static int nmclan_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
mace_private *lp = netdev_priv(dev);
|
mace_private *lp = netdev_priv(dev);
|
||||||
tuple_t tuple;
|
u8 *buf;
|
||||||
u_char buf[64];
|
size_t len;
|
||||||
int i, last_ret, last_fn;
|
int i, ret;
|
||||||
unsigned int ioaddr;
|
unsigned int ioaddr;
|
||||||
|
|
||||||
DEBUG(0, "nmclan_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "nmclan_config\n");
|
||||||
|
|
||||||
|
ret = pcmcia_request_io(link, &link->io);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
|
|
||||||
ioaddr = dev->base_addr;
|
ioaddr = dev->base_addr;
|
||||||
|
|
||||||
/* Read the ethernet address from the CIS. */
|
/* Read the ethernet address from the CIS. */
|
||||||
tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
|
len = pcmcia_get_tuple(link, 0x80, &buf);
|
||||||
tuple.TupleData = buf;
|
if (!buf || len < ETHER_ADDR_LEN) {
|
||||||
tuple.TupleDataMax = 64;
|
kfree(buf);
|
||||||
tuple.TupleOffset = 0;
|
goto failed;
|
||||||
tuple.Attributes = 0;
|
}
|
||||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
|
||||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
kfree(buf);
|
||||||
memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
|
|
||||||
|
|
||||||
/* Verify configuration by reading the MACE ID. */
|
/* Verify configuration by reading the MACE ID. */
|
||||||
{
|
{
|
||||||
@ -693,7 +680,7 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||||||
sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
|
sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
|
||||||
sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
|
sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
|
||||||
if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
|
if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
|
||||||
DEBUG(0, "nmclan_cs configured: mace id=%x %x\n",
|
dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
|
||||||
sig[0], sig[1]);
|
sig[0], sig[1]);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
|
printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
|
||||||
@ -712,7 +699,7 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||||||
printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
|
printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
|
||||||
|
|
||||||
link->dev_node = &lp->node;
|
link->dev_node = &lp->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
i = register_netdev(dev);
|
i = register_netdev(dev);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
@ -729,8 +716,6 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||||||
dev->dev_addr);
|
dev->dev_addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
nmclan_release(link);
|
nmclan_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -744,7 +729,7 @@ nmclan_release
|
|||||||
---------------------------------------------------------------------------- */
|
---------------------------------------------------------------------------- */
|
||||||
static void nmclan_release(struct pcmcia_device *link)
|
static void nmclan_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "nmclan_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "nmclan_release\n");
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,7 +780,7 @@ static void nmclan_reset(struct net_device *dev)
|
|||||||
/* Reset Xilinx */
|
/* Reset Xilinx */
|
||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Offset = CISREG_COR;
|
reg.Offset = CISREG_COR;
|
||||||
DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
|
dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
|
||||||
OrigCorValue);
|
OrigCorValue);
|
||||||
reg.Value = COR_SOFT_RESET;
|
reg.Value = COR_SOFT_RESET;
|
||||||
pcmcia_access_configuration_register(link, ®);
|
pcmcia_access_configuration_register(link, ®);
|
||||||
@ -872,7 +857,7 @@ static int mace_close(struct net_device *dev)
|
|||||||
mace_private *lp = netdev_priv(dev);
|
mace_private *lp = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = lp->p_dev;
|
struct pcmcia_device *link = lp->p_dev;
|
||||||
|
|
||||||
DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
|
dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
|
||||||
|
|
||||||
/* Mask off all interrupts from the MACE chip. */
|
/* Mask off all interrupts from the MACE chip. */
|
||||||
outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
|
outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
|
||||||
@ -891,24 +876,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
|
|||||||
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static u32 netdev_get_msglevel(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return pc_debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void netdev_set_msglevel(struct net_device *dev, u32 level)
|
|
||||||
{
|
|
||||||
pc_debug = level;
|
|
||||||
}
|
|
||||||
#endif /* PCMCIA_DEBUG */
|
|
||||||
|
|
||||||
static const struct ethtool_ops netdev_ethtool_ops = {
|
static const struct ethtool_ops netdev_ethtool_ops = {
|
||||||
.get_drvinfo = netdev_get_drvinfo,
|
.get_drvinfo = netdev_get_drvinfo,
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
.get_msglevel = netdev_get_msglevel,
|
|
||||||
.set_msglevel = netdev_set_msglevel,
|
|
||||||
#endif /* PCMCIA_DEBUG */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
@ -946,7 +915,7 @@ static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
|
|||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
|
pr_debug("%s: mace_start_xmit(length = %ld) called.\n",
|
||||||
dev->name, (long)skb->len);
|
dev->name, (long)skb->len);
|
||||||
|
|
||||||
#if (!TX_INTERRUPTABLE)
|
#if (!TX_INTERRUPTABLE)
|
||||||
@ -1008,7 +977,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
|
|||||||
int IntrCnt = MACE_MAX_IR_ITERATIONS;
|
int IntrCnt = MACE_MAX_IR_ITERATIONS;
|
||||||
|
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
|
pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
|
||||||
irq);
|
irq);
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
@ -1031,7 +1000,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!netif_device_present(dev)) {
|
if (!netif_device_present(dev)) {
|
||||||
DEBUG(2, "%s: interrupt from dead card\n", dev->name);
|
pr_debug("%s: interrupt from dead card\n", dev->name);
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,7 +1008,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
|
|||||||
/* WARNING: MACE_IR is a READ/CLEAR port! */
|
/* WARNING: MACE_IR is a READ/CLEAR port! */
|
||||||
status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
|
status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
|
||||||
|
|
||||||
DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
|
pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
|
||||||
|
|
||||||
if (status & MACE_IR_RCVINT) {
|
if (status & MACE_IR_RCVINT) {
|
||||||
mace_rx(dev, MACE_MAX_RX_ITERATIONS);
|
mace_rx(dev, MACE_MAX_RX_ITERATIONS);
|
||||||
@ -1158,7 +1127,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
|
|||||||
) {
|
) {
|
||||||
rx_status = inw(ioaddr + AM2150_RCV);
|
rx_status = inw(ioaddr + AM2150_RCV);
|
||||||
|
|
||||||
DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status"
|
pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
|
||||||
" 0x%X.\n", dev->name, rx_framecnt, rx_status);
|
" 0x%X.\n", dev->name, rx_framecnt, rx_status);
|
||||||
|
|
||||||
if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
|
if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
|
||||||
@ -1185,7 +1154,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
|
|||||||
lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
|
lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
|
||||||
/* rcv collision count */
|
/* rcv collision count */
|
||||||
|
|
||||||
DEBUG(3, " receiving packet size 0x%X rx_status"
|
pr_debug(" receiving packet size 0x%X rx_status"
|
||||||
" 0x%X.\n", pkt_len, rx_status);
|
" 0x%X.\n", pkt_len, rx_status);
|
||||||
|
|
||||||
skb = dev_alloc_skb(pkt_len+2);
|
skb = dev_alloc_skb(pkt_len+2);
|
||||||
@ -1204,7 +1173,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
|
|||||||
outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
|
outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
DEBUG(1, "%s: couldn't allocate a sk_buff of size"
|
pr_debug("%s: couldn't allocate a sk_buff of size"
|
||||||
" %d.\n", dev->name, pkt_len);
|
" %d.\n", dev->name, pkt_len);
|
||||||
lp->linux_stats.rx_dropped++;
|
lp->linux_stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
@ -1220,28 +1189,28 @@ pr_linux_stats
|
|||||||
---------------------------------------------------------------------------- */
|
---------------------------------------------------------------------------- */
|
||||||
static void pr_linux_stats(struct net_device_stats *pstats)
|
static void pr_linux_stats(struct net_device_stats *pstats)
|
||||||
{
|
{
|
||||||
DEBUG(2, "pr_linux_stats\n");
|
pr_debug("pr_linux_stats\n");
|
||||||
DEBUG(2, " rx_packets=%-7ld tx_packets=%ld\n",
|
pr_debug(" rx_packets=%-7ld tx_packets=%ld\n",
|
||||||
(long)pstats->rx_packets, (long)pstats->tx_packets);
|
(long)pstats->rx_packets, (long)pstats->tx_packets);
|
||||||
DEBUG(2, " rx_errors=%-7ld tx_errors=%ld\n",
|
pr_debug(" rx_errors=%-7ld tx_errors=%ld\n",
|
||||||
(long)pstats->rx_errors, (long)pstats->tx_errors);
|
(long)pstats->rx_errors, (long)pstats->tx_errors);
|
||||||
DEBUG(2, " rx_dropped=%-7ld tx_dropped=%ld\n",
|
pr_debug(" rx_dropped=%-7ld tx_dropped=%ld\n",
|
||||||
(long)pstats->rx_dropped, (long)pstats->tx_dropped);
|
(long)pstats->rx_dropped, (long)pstats->tx_dropped);
|
||||||
DEBUG(2, " multicast=%-7ld collisions=%ld\n",
|
pr_debug(" multicast=%-7ld collisions=%ld\n",
|
||||||
(long)pstats->multicast, (long)pstats->collisions);
|
(long)pstats->multicast, (long)pstats->collisions);
|
||||||
|
|
||||||
DEBUG(2, " rx_length_errors=%-7ld rx_over_errors=%ld\n",
|
pr_debug(" rx_length_errors=%-7ld rx_over_errors=%ld\n",
|
||||||
(long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
|
(long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
|
||||||
DEBUG(2, " rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
|
pr_debug(" rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
|
||||||
(long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
|
(long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
|
||||||
DEBUG(2, " rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
|
pr_debug(" rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
|
||||||
(long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
|
(long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
|
||||||
|
|
||||||
DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
|
pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
|
||||||
(long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
|
(long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
|
||||||
DEBUG(2, " tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
|
pr_debug(" tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
|
||||||
(long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
|
(long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
|
||||||
DEBUG(2, " tx_window_errors=%ld\n",
|
pr_debug(" tx_window_errors=%ld\n",
|
||||||
(long)pstats->tx_window_errors);
|
(long)pstats->tx_window_errors);
|
||||||
} /* pr_linux_stats */
|
} /* pr_linux_stats */
|
||||||
|
|
||||||
@ -1250,48 +1219,48 @@ pr_mace_stats
|
|||||||
---------------------------------------------------------------------------- */
|
---------------------------------------------------------------------------- */
|
||||||
static void pr_mace_stats(mace_statistics *pstats)
|
static void pr_mace_stats(mace_statistics *pstats)
|
||||||
{
|
{
|
||||||
DEBUG(2, "pr_mace_stats\n");
|
pr_debug("pr_mace_stats\n");
|
||||||
|
|
||||||
DEBUG(2, " xmtsv=%-7d uflo=%d\n",
|
pr_debug(" xmtsv=%-7d uflo=%d\n",
|
||||||
pstats->xmtsv, pstats->uflo);
|
pstats->xmtsv, pstats->uflo);
|
||||||
DEBUG(2, " lcol=%-7d more=%d\n",
|
pr_debug(" lcol=%-7d more=%d\n",
|
||||||
pstats->lcol, pstats->more);
|
pstats->lcol, pstats->more);
|
||||||
DEBUG(2, " one=%-7d defer=%d\n",
|
pr_debug(" one=%-7d defer=%d\n",
|
||||||
pstats->one, pstats->defer);
|
pstats->one, pstats->defer);
|
||||||
DEBUG(2, " lcar=%-7d rtry=%d\n",
|
pr_debug(" lcar=%-7d rtry=%d\n",
|
||||||
pstats->lcar, pstats->rtry);
|
pstats->lcar, pstats->rtry);
|
||||||
|
|
||||||
/* MACE_XMTRC */
|
/* MACE_XMTRC */
|
||||||
DEBUG(2, " exdef=%-7d xmtrc=%d\n",
|
pr_debug(" exdef=%-7d xmtrc=%d\n",
|
||||||
pstats->exdef, pstats->xmtrc);
|
pstats->exdef, pstats->xmtrc);
|
||||||
|
|
||||||
/* RFS1--Receive Status (RCVSTS) */
|
/* RFS1--Receive Status (RCVSTS) */
|
||||||
DEBUG(2, " oflo=%-7d clsn=%d\n",
|
pr_debug(" oflo=%-7d clsn=%d\n",
|
||||||
pstats->oflo, pstats->clsn);
|
pstats->oflo, pstats->clsn);
|
||||||
DEBUG(2, " fram=%-7d fcs=%d\n",
|
pr_debug(" fram=%-7d fcs=%d\n",
|
||||||
pstats->fram, pstats->fcs);
|
pstats->fram, pstats->fcs);
|
||||||
|
|
||||||
/* RFS2--Runt Packet Count (RNTPC) */
|
/* RFS2--Runt Packet Count (RNTPC) */
|
||||||
/* RFS3--Receive Collision Count (RCVCC) */
|
/* RFS3--Receive Collision Count (RCVCC) */
|
||||||
DEBUG(2, " rfs_rntpc=%-7d rfs_rcvcc=%d\n",
|
pr_debug(" rfs_rntpc=%-7d rfs_rcvcc=%d\n",
|
||||||
pstats->rfs_rntpc, pstats->rfs_rcvcc);
|
pstats->rfs_rntpc, pstats->rfs_rcvcc);
|
||||||
|
|
||||||
/* MACE_IR */
|
/* MACE_IR */
|
||||||
DEBUG(2, " jab=%-7d babl=%d\n",
|
pr_debug(" jab=%-7d babl=%d\n",
|
||||||
pstats->jab, pstats->babl);
|
pstats->jab, pstats->babl);
|
||||||
DEBUG(2, " cerr=%-7d rcvcco=%d\n",
|
pr_debug(" cerr=%-7d rcvcco=%d\n",
|
||||||
pstats->cerr, pstats->rcvcco);
|
pstats->cerr, pstats->rcvcco);
|
||||||
DEBUG(2, " rntpco=%-7d mpco=%d\n",
|
pr_debug(" rntpco=%-7d mpco=%d\n",
|
||||||
pstats->rntpco, pstats->mpco);
|
pstats->rntpco, pstats->mpco);
|
||||||
|
|
||||||
/* MACE_MPC */
|
/* MACE_MPC */
|
||||||
DEBUG(2, " mpc=%d\n", pstats->mpc);
|
pr_debug(" mpc=%d\n", pstats->mpc);
|
||||||
|
|
||||||
/* MACE_RNTPC */
|
/* MACE_RNTPC */
|
||||||
DEBUG(2, " rntpc=%d\n", pstats->rntpc);
|
pr_debug(" rntpc=%d\n", pstats->rntpc);
|
||||||
|
|
||||||
/* MACE_RCVCC */
|
/* MACE_RCVCC */
|
||||||
DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);
|
pr_debug(" rcvcc=%d\n", pstats->rcvcc);
|
||||||
|
|
||||||
} /* pr_mace_stats */
|
} /* pr_mace_stats */
|
||||||
|
|
||||||
@ -1360,7 +1329,7 @@ static struct net_device_stats *mace_get_stats(struct net_device *dev)
|
|||||||
|
|
||||||
update_stats(dev->base_addr, dev);
|
update_stats(dev->base_addr, dev);
|
||||||
|
|
||||||
DEBUG(1, "%s: updating the statistics.\n", dev->name);
|
pr_debug("%s: updating the statistics.\n", dev->name);
|
||||||
pr_linux_stats(&lp->linux_stats);
|
pr_linux_stats(&lp->linux_stats);
|
||||||
pr_mace_stats(&lp->mace_stats);
|
pr_mace_stats(&lp->mace_stats);
|
||||||
|
|
||||||
@ -1427,7 +1396,7 @@ static void BuildLAF(int *ladrf, int *adr)
|
|||||||
ladrf[byte] |= (1 << (hashcode & 7));
|
ladrf[byte] |= (1 << (hashcode & 7));
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef PCMCIA_DEBUG
|
||||||
if (pc_debug > 2)
|
if (0)
|
||||||
printk(KERN_DEBUG " adr =%pM\n", adr);
|
printk(KERN_DEBUG " adr =%pM\n", adr);
|
||||||
printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
|
printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
@ -1454,12 +1423,12 @@ static void restore_multicast_list(struct net_device *dev)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
|
pr_debug("%s: restoring Rx mode to %d addresses.\n",
|
||||||
dev->name, num_addrs);
|
dev->name, num_addrs);
|
||||||
|
|
||||||
if (num_addrs > 0) {
|
if (num_addrs > 0) {
|
||||||
|
|
||||||
DEBUG(1, "Attempt to restore multicast list detected.\n");
|
pr_debug("Attempt to restore multicast list detected.\n");
|
||||||
|
|
||||||
mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
|
mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
|
||||||
/* Poll ADDRCHG bit */
|
/* Poll ADDRCHG bit */
|
||||||
@ -1511,11 +1480,11 @@ static void set_multicast_list(struct net_device *dev)
|
|||||||
struct dev_mc_list *dmi = dev->mc_list;
|
struct dev_mc_list *dmi = dev->mc_list;
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef PCMCIA_DEBUG
|
||||||
if (pc_debug > 1) {
|
{
|
||||||
static int old;
|
static int old;
|
||||||
if (dev->mc_count != old) {
|
if (dev->mc_count != old) {
|
||||||
old = dev->mc_count;
|
old = dev->mc_count;
|
||||||
DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
|
pr_debug("%s: setting Rx mode to %d addresses.\n",
|
||||||
dev->name, old);
|
dev->name, old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1546,7 +1515,7 @@ static void restore_multicast_list(struct net_device *dev)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
mace_private *lp = netdev_priv(dev);
|
mace_private *lp = netdev_priv(dev);
|
||||||
|
|
||||||
DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
|
pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
|
||||||
lp->multicast_num_addrs);
|
lp->multicast_num_addrs);
|
||||||
|
|
||||||
if (dev->flags & IFF_PROMISC) {
|
if (dev->flags & IFF_PROMISC) {
|
||||||
@ -1567,11 +1536,11 @@ static void set_multicast_list(struct net_device *dev)
|
|||||||
mace_private *lp = netdev_priv(dev);
|
mace_private *lp = netdev_priv(dev);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef PCMCIA_DEBUG
|
||||||
if (pc_debug > 1) {
|
{
|
||||||
static int old;
|
static int old;
|
||||||
if (dev->mc_count != old) {
|
if (dev->mc_count != old) {
|
||||||
old = dev->mc_count;
|
old = dev->mc_count;
|
||||||
DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
|
pr_debug("%s: setting Rx mode to %d addresses.\n",
|
||||||
dev->name, old);
|
dev->name, old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,15 +71,6 @@
|
|||||||
|
|
||||||
static const char *if_names[] = { "auto", "10baseT", "10base2"};
|
static const char *if_names[] = { "auto", "10baseT", "10base2"};
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -265,7 +256,7 @@ static int pcnet_probe(struct pcmcia_device *link)
|
|||||||
pcnet_dev_t *info;
|
pcnet_dev_t *info;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
DEBUG(0, "pcnet_attach()\n");
|
dev_dbg(&link->dev, "pcnet_attach()\n");
|
||||||
|
|
||||||
/* Create new ethernet device */
|
/* Create new ethernet device */
|
||||||
dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
|
dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
|
||||||
@ -275,7 +266,6 @@ static int pcnet_probe(struct pcmcia_device *link)
|
|||||||
link->priv = dev;
|
link->priv = dev;
|
||||||
|
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -297,7 +287,7 @@ static void pcnet_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "pcnet_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "pcnet_detach\n");
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -326,17 +316,15 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
|
|||||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||||
req.Base = 0; req.Size = 0;
|
req.Base = 0; req.Size = 0;
|
||||||
req.AccessSpeed = 0;
|
req.AccessSpeed = 0;
|
||||||
i = pcmcia_request_window(&link, &req, &link->win);
|
i = pcmcia_request_window(link, &req, &link->win);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestWindow, i);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
virt = ioremap(req.Base, req.Size);
|
virt = ioremap(req.Base, req.Size);
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
for (i = 0; i < NR_INFO; i++) {
|
for (i = 0; i < NR_INFO; i++) {
|
||||||
mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
|
mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
|
||||||
pcmcia_map_mem_page(link->win, &mem);
|
pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
base = &virt[hw_info[i].offset & (req.Size-1)];
|
base = &virt[hw_info[i].offset & (req.Size-1)];
|
||||||
if ((readb(base+0) == hw_info[i].a0) &&
|
if ((readb(base+0) == hw_info[i].a0) &&
|
||||||
(readb(base+2) == hw_info[i].a1) &&
|
(readb(base+2) == hw_info[i].a1) &&
|
||||||
@ -348,9 +336,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
iounmap(virt);
|
iounmap(virt);
|
||||||
j = pcmcia_release_window(link->win);
|
j = pcmcia_release_window(link, link->win);
|
||||||
if (j != 0)
|
|
||||||
cs_error(link, ReleaseWindow, j);
|
|
||||||
return (i < NR_INFO) ? hw_info+i : NULL;
|
return (i < NR_INFO) ? hw_info+i : NULL;
|
||||||
} /* get_hwinfo */
|
} /* get_hwinfo */
|
||||||
|
|
||||||
@ -495,9 +481,6 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int try_io_port(struct pcmcia_device *link)
|
static int try_io_port(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
int j, ret;
|
int j, ret;
|
||||||
@ -567,19 +550,19 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
pcnet_dev_t *info = PRIV(dev);
|
pcnet_dev_t *info = PRIV(dev);
|
||||||
int last_ret, last_fn, start_pg, stop_pg, cm_offset;
|
int ret, start_pg, stop_pg, cm_offset;
|
||||||
int has_shmem = 0;
|
int has_shmem = 0;
|
||||||
hw_info_t *local_hw_info;
|
hw_info_t *local_hw_info;
|
||||||
|
|
||||||
DEBUG(0, "pcnet_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "pcnet_config\n");
|
||||||
|
|
||||||
last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
|
ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
if (link->io.NumPorts2 == 8) {
|
if (link->io.NumPorts2 == 8) {
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
@ -589,7 +572,9 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||||||
(link->card_id == PRODID_IBM_HOME_AND_AWAY))
|
(link->card_id == PRODID_IBM_HOME_AND_AWAY))
|
||||||
link->conf.ConfigIndex |= 0x10;
|
link->conf.ConfigIndex |= 0x10;
|
||||||
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
if (info->flags & HAS_MISC_REG) {
|
if (info->flags & HAS_MISC_REG) {
|
||||||
@ -660,7 +645,7 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||||||
mii_phy_probe(dev);
|
mii_phy_probe(dev);
|
||||||
|
|
||||||
link->dev_node = &info->node;
|
link->dev_node = &info->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if (register_netdev(dev) != 0) {
|
if (register_netdev(dev) != 0) {
|
||||||
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
|
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
|
||||||
@ -687,8 +672,6 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||||||
printk(" hw_addr %pM\n", dev->dev_addr);
|
printk(" hw_addr %pM\n", dev->dev_addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
pcnet_release(link);
|
pcnet_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -706,7 +689,7 @@ static void pcnet_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
pcnet_dev_t *info = PRIV(link->priv);
|
pcnet_dev_t *info = PRIV(link->priv);
|
||||||
|
|
||||||
DEBUG(0, "pcnet_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "pcnet_release\n");
|
||||||
|
|
||||||
if (info->flags & USE_SHMEM)
|
if (info->flags & USE_SHMEM)
|
||||||
iounmap(info->base);
|
iounmap(info->base);
|
||||||
@ -960,7 +943,7 @@ static void mii_phy_probe(struct net_device *dev)
|
|||||||
phyid = tmp << 16;
|
phyid = tmp << 16;
|
||||||
phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
|
phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
|
||||||
phyid &= MII_PHYID_REV_MASK;
|
phyid &= MII_PHYID_REV_MASK;
|
||||||
DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
|
pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
|
||||||
if (phyid == AM79C9XX_HOME_PHY) {
|
if (phyid == AM79C9XX_HOME_PHY) {
|
||||||
info->pna_phy = i;
|
info->pna_phy = i;
|
||||||
} else if (phyid != AM79C9XX_ETH_PHY) {
|
} else if (phyid != AM79C9XX_ETH_PHY) {
|
||||||
@ -976,7 +959,7 @@ static int pcnet_open(struct net_device *dev)
|
|||||||
struct pcmcia_device *link = info->p_dev;
|
struct pcmcia_device *link = info->p_dev;
|
||||||
unsigned int nic_base = dev->base_addr;
|
unsigned int nic_base = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(2, "pcnet_open('%s')\n", dev->name);
|
dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name);
|
||||||
|
|
||||||
if (!pcmcia_dev_present(link))
|
if (!pcmcia_dev_present(link))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -1008,7 +991,7 @@ static int pcnet_close(struct net_device *dev)
|
|||||||
pcnet_dev_t *info = PRIV(dev);
|
pcnet_dev_t *info = PRIV(dev);
|
||||||
struct pcmcia_device *link = info->p_dev;
|
struct pcmcia_device *link = info->p_dev;
|
||||||
|
|
||||||
DEBUG(2, "pcnet_close('%s')\n", dev->name);
|
dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name);
|
||||||
|
|
||||||
ei_close(dev);
|
ei_close(dev);
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
@ -1251,10 +1234,8 @@ static void dma_block_input(struct net_device *dev, int count,
|
|||||||
int xfer_count = count;
|
int xfer_count = count;
|
||||||
char *buf = skb->data;
|
char *buf = skb->data;
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
if ((ei_debug > 4) && (count != 4))
|
if ((ei_debug > 4) && (count != 4))
|
||||||
printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
|
pr_debug("%s: [bi=%d]\n", dev->name, count+4);
|
||||||
#endif
|
|
||||||
if (ei_status.dmaing) {
|
if (ei_status.dmaing) {
|
||||||
printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
|
printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
|
||||||
"[DMAstat:%1x][irqlock:%1x]\n",
|
"[DMAstat:%1x][irqlock:%1x]\n",
|
||||||
@ -1495,7 +1476,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||||||
pcnet_dev_t *info = PRIV(dev);
|
pcnet_dev_t *info = PRIV(dev);
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
memreq_t mem;
|
memreq_t mem;
|
||||||
int i, window_size, offset, last_ret, last_fn;
|
int i, window_size, offset, ret;
|
||||||
|
|
||||||
window_size = (stop_pg - start_pg) << 8;
|
window_size = (stop_pg - start_pg) << 8;
|
||||||
if (window_size > 32 * 1024)
|
if (window_size > 32 * 1024)
|
||||||
@ -1509,13 +1490,17 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||||||
req.Attributes |= WIN_USE_WAIT;
|
req.Attributes |= WIN_USE_WAIT;
|
||||||
req.Base = 0; req.Size = window_size;
|
req.Base = 0; req.Size = window_size;
|
||||||
req.AccessSpeed = mem_speed;
|
req.AccessSpeed = mem_speed;
|
||||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
ret = pcmcia_request_window(link, &req, &link->win);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
mem.CardOffset = (start_pg << 8) + cm_offset;
|
mem.CardOffset = (start_pg << 8) + cm_offset;
|
||||||
offset = mem.CardOffset % window_size;
|
offset = mem.CardOffset % window_size;
|
||||||
mem.CardOffset -= offset;
|
mem.CardOffset -= offset;
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
|
ret = pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* Try scribbling on the buffer */
|
/* Try scribbling on the buffer */
|
||||||
info->base = ioremap(req.Base, window_size);
|
info->base = ioremap(req.Base, window_size);
|
||||||
@ -1527,8 +1512,8 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||||||
pcnet_reset_8390(dev);
|
pcnet_reset_8390(dev);
|
||||||
if (i != (TX_PAGES<<8)) {
|
if (i != (TX_PAGES<<8)) {
|
||||||
iounmap(info->base);
|
iounmap(info->base);
|
||||||
pcmcia_release_window(link->win);
|
pcmcia_release_window(link, link->win);
|
||||||
info->base = NULL; link->win = NULL;
|
info->base = NULL; link->win = 0;
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1549,8 +1534,6 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||||||
info->flags |= USE_SHMEM;
|
info->flags |= USE_SHMEM;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1788,7 +1771,6 @@ static int __init init_pcnet_cs(void)
|
|||||||
|
|
||||||
static void __exit exit_pcnet_cs(void)
|
static void __exit exit_pcnet_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "pcnet_cs: unloading\n");
|
|
||||||
pcmcia_unregister_driver(&pcnet_driver);
|
pcmcia_unregister_driver(&pcnet_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,14 +79,6 @@ MODULE_FIRMWARE(FIRMWARE_NAME);
|
|||||||
*/
|
*/
|
||||||
INT_MODULE_PARM(if_port, 0);
|
INT_MODULE_PARM(if_port, 0);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|
||||||
static const char *version =
|
|
||||||
"smc91c92_cs.c 1.123 2006/11/09 Donald Becker, becker@scyld.com.\n";
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DRV_NAME "smc91c92_cs"
|
#define DRV_NAME "smc91c92_cs"
|
||||||
#define DRV_VERSION "1.123"
|
#define DRV_VERSION "1.123"
|
||||||
@ -126,12 +118,6 @@ struct smc_private {
|
|||||||
int rx_ovrn;
|
int rx_ovrn;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct smc_cfg_mem {
|
|
||||||
tuple_t tuple;
|
|
||||||
cisparse_t parse;
|
|
||||||
u_char buf[255];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Special definitions for Megahertz multifunction cards */
|
/* Special definitions for Megahertz multifunction cards */
|
||||||
#define MEGAHERTZ_ISR 0x0380
|
#define MEGAHERTZ_ISR 0x0380
|
||||||
|
|
||||||
@ -329,7 +315,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
|
|||||||
struct smc_private *smc;
|
struct smc_private *smc;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
DEBUG(0, "smc91c92_attach()\n");
|
dev_dbg(&link->dev, "smc91c92_attach()\n");
|
||||||
|
|
||||||
/* Create new ethernet device */
|
/* Create new ethernet device */
|
||||||
dev = alloc_etherdev(sizeof(struct smc_private));
|
dev = alloc_etherdev(sizeof(struct smc_private));
|
||||||
@ -343,10 +329,8 @@ static int smc91c92_probe(struct pcmcia_device *link)
|
|||||||
link->io.NumPorts1 = 16;
|
link->io.NumPorts1 = 16;
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
link->io.IOAddrLines = 4;
|
link->io.IOAddrLines = 4;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = &smc_interrupt;
|
link->irq.Handler = &smc_interrupt;
|
||||||
link->irq.Instance = dev;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -377,7 +361,7 @@ static void smc91c92_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "smc91c92_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "smc91c92_detach\n");
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -408,34 +392,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================
|
||||||
|
|
||||||
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
|
|
||||||
cisparse_t *parse)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = pcmcia_get_first_tuple(handle, tuple);
|
|
||||||
if (i != 0)
|
|
||||||
return i;
|
|
||||||
i = pcmcia_get_tuple_data(handle, tuple);
|
|
||||||
if (i != 0)
|
|
||||||
return i;
|
|
||||||
return pcmcia_parse_tuple(tuple, parse);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
|
|
||||||
cisparse_t *parse)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
|
|
||||||
(i = pcmcia_get_tuple_data(handle, tuple)) != 0)
|
|
||||||
return i;
|
|
||||||
return pcmcia_parse_tuple(tuple, parse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*======================================================================
|
|
||||||
|
|
||||||
Configuration stuff for Megahertz cards
|
Configuration stuff for Megahertz cards
|
||||||
|
|
||||||
@ -490,19 +447,14 @@ static int mhz_mfc_config(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
struct smc_private *smc = netdev_priv(dev);
|
struct smc_private *smc = netdev_priv(dev);
|
||||||
struct smc_cfg_mem *cfg_mem;
|
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
memreq_t mem;
|
memreq_t mem;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
|
||||||
if (!cfg_mem)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
link->conf.Status = CCSR_AUDIO_ENA;
|
||||||
link->irq.Attributes =
|
link->irq.Attributes =
|
||||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
|
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
link->io.IOAddrLines = 16;
|
link->io.IOAddrLines = 16;
|
||||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts2 = 8;
|
link->io.NumPorts2 = 8;
|
||||||
@ -510,91 +462,80 @@ static int mhz_mfc_config(struct pcmcia_device *link)
|
|||||||
/* The Megahertz combo cards have modem-like CIS entries, so
|
/* The Megahertz combo cards have modem-like CIS entries, so
|
||||||
we have to explicitly try a bunch of port combinations. */
|
we have to explicitly try a bunch of port combinations. */
|
||||||
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
|
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
|
||||||
goto free_cfg_mem;
|
return -ENODEV;
|
||||||
|
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
|
|
||||||
/* Allocate a memory window, for accessing the ISR */
|
/* Allocate a memory window, for accessing the ISR */
|
||||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||||
req.Base = req.Size = 0;
|
req.Base = req.Size = 0;
|
||||||
req.AccessSpeed = 0;
|
req.AccessSpeed = 0;
|
||||||
i = pcmcia_request_window(&link, &req, &link->win);
|
i = pcmcia_request_window(link, &req, &link->win);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
goto free_cfg_mem;
|
return -ENODEV;
|
||||||
|
|
||||||
smc->base = ioremap(req.Base, req.Size);
|
smc->base = ioremap(req.Base, req.Size);
|
||||||
mem.CardOffset = mem.Page = 0;
|
mem.CardOffset = mem.Page = 0;
|
||||||
if (smc->manfid == MANFID_MOTOROLA)
|
if (smc->manfid == MANFID_MOTOROLA)
|
||||||
mem.CardOffset = link->conf.ConfigBase;
|
mem.CardOffset = link->conf.ConfigBase;
|
||||||
i = pcmcia_map_mem_page(link->win, &mem);
|
i = pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
|
|
||||||
if ((i == 0)
|
if ((i == 0)
|
||||||
&& (smc->manfid == MANFID_MEGAHERTZ)
|
&& (smc->manfid == MANFID_MEGAHERTZ)
|
||||||
&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
|
&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
|
||||||
mhz_3288_power(link);
|
mhz_3288_power(link);
|
||||||
|
|
||||||
free_cfg_mem:
|
return 0;
|
||||||
kfree(cfg_mem);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
struct net_device *dev = priv;
|
||||||
|
cisparse_t parse;
|
||||||
|
|
||||||
|
if (pcmcia_parse_tuple(tuple, &parse))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((parse.version_1.ns > 3) &&
|
||||||
|
(cvt_ascii_address(dev,
|
||||||
|
(parse.version_1.str + parse.version_1.ofs[3]))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
};
|
||||||
|
|
||||||
static int mhz_setup(struct pcmcia_device *link)
|
static int mhz_setup(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
struct smc_cfg_mem *cfg_mem;
|
size_t len;
|
||||||
tuple_t *tuple;
|
u8 *buf;
|
||||||
cisparse_t *parse;
|
|
||||||
u_char *buf, *station_addr;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
|
||||||
if (!cfg_mem)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
tuple = &cfg_mem->tuple;
|
|
||||||
parse = &cfg_mem->parse;
|
|
||||||
buf = cfg_mem->buf;
|
|
||||||
|
|
||||||
tuple->Attributes = tuple->TupleOffset = 0;
|
|
||||||
tuple->TupleData = (cisdata_t *)buf;
|
|
||||||
tuple->TupleDataMax = 255;
|
|
||||||
|
|
||||||
/* Read the station address from the CIS. It is stored as the last
|
/* Read the station address from the CIS. It is stored as the last
|
||||||
(fourth) string in the Version 1 Version/ID tuple. */
|
(fourth) string in the Version 1 Version/ID tuple. */
|
||||||
tuple->DesiredTuple = CISTPL_VERS_1;
|
if ((link->prod_id[3]) &&
|
||||||
if (first_tuple(link, tuple, parse) != 0) {
|
(cvt_ascii_address(dev, link->prod_id[3]) == 0))
|
||||||
rc = -1;
|
return 0;
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
/* Workarounds for broken cards start here. */
|
||||||
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
|
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
|
||||||
if (next_tuple(link, tuple, parse) != 0)
|
if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
|
||||||
first_tuple(link, tuple, parse);
|
return 0;
|
||||||
if (parse->version_1.ns > 3) {
|
|
||||||
station_addr = parse->version_1.str + parse->version_1.ofs[3];
|
|
||||||
if (cvt_ascii_address(dev, station_addr) == 0) {
|
|
||||||
rc = 0;
|
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Another possibility: for the EM3288, in a special tuple */
|
/* Another possibility: for the EM3288, in a special tuple */
|
||||||
tuple->DesiredTuple = 0x81;
|
|
||||||
if (pcmcia_get_first_tuple(link, tuple) != 0) {
|
|
||||||
rc = -1;
|
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
|
||||||
if (pcmcia_get_tuple_data(link, tuple) != 0) {
|
|
||||||
rc = -1;
|
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
|
||||||
buf[12] = '\0';
|
|
||||||
if (cvt_ascii_address(dev, buf) == 0) {
|
|
||||||
rc = 0;
|
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
|
||||||
rc = -1;
|
rc = -1;
|
||||||
free_cfg_mem:
|
len = pcmcia_get_tuple(link, 0x81, &buf);
|
||||||
kfree(cfg_mem);
|
if (buf && len >= 13) {
|
||||||
return rc;
|
buf[12] = '\0';
|
||||||
}
|
if (cvt_ascii_address(dev, buf))
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
};
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
|
|
||||||
@ -684,58 +625,21 @@ static int smc_config(struct pcmcia_device *link)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int smc_setup(struct pcmcia_device *link)
|
static int smc_setup(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
struct smc_cfg_mem *cfg_mem;
|
|
||||||
tuple_t *tuple;
|
|
||||||
cisparse_t *parse;
|
|
||||||
cistpl_lan_node_id_t *node_id;
|
|
||||||
u_char *buf, *station_addr;
|
|
||||||
int i, rc;
|
|
||||||
|
|
||||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
|
||||||
if (!cfg_mem)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
tuple = &cfg_mem->tuple;
|
|
||||||
parse = &cfg_mem->parse;
|
|
||||||
buf = cfg_mem->buf;
|
|
||||||
|
|
||||||
tuple->Attributes = tuple->TupleOffset = 0;
|
|
||||||
tuple->TupleData = (cisdata_t *)buf;
|
|
||||||
tuple->TupleDataMax = 255;
|
|
||||||
|
|
||||||
/* Check for a LAN function extension tuple */
|
/* Check for a LAN function extension tuple */
|
||||||
tuple->DesiredTuple = CISTPL_FUNCE;
|
if (!pcmcia_get_mac_from_cis(link, dev))
|
||||||
i = first_tuple(link, tuple, parse);
|
return 0;
|
||||||
while (i == 0) {
|
|
||||||
if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
|
|
||||||
break;
|
|
||||||
i = next_tuple(link, tuple, parse);
|
|
||||||
}
|
|
||||||
if (i == 0) {
|
|
||||||
node_id = (cistpl_lan_node_id_t *)parse->funce.data;
|
|
||||||
if (node_id->nb == 6) {
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
dev->dev_addr[i] = node_id->id[i];
|
|
||||||
rc = 0;
|
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Try the third string in the Version 1 Version/ID tuple. */
|
/* Try the third string in the Version 1 Version/ID tuple. */
|
||||||
if (link->prod_id[2]) {
|
if (link->prod_id[2]) {
|
||||||
station_addr = link->prod_id[2];
|
if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
|
||||||
if (cvt_ascii_address(dev, station_addr) == 0) {
|
return 0;
|
||||||
rc = 0;
|
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
rc = -1;
|
|
||||||
free_cfg_mem:
|
|
||||||
kfree(cfg_mem);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
@ -749,7 +653,7 @@ static int osi_config(struct pcmcia_device *link)
|
|||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
link->conf.Status = CCSR_AUDIO_ENA;
|
||||||
link->irq.Attributes =
|
link->irq.Attributes =
|
||||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
|
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||||
link->io.NumPorts1 = 64;
|
link->io.NumPorts1 = 64;
|
||||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts2 = 8;
|
link->io.NumPorts2 = 8;
|
||||||
@ -794,41 +698,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
struct net_device *dev = priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (tuple->TupleDataLen < 8)
|
||||||
|
return -EINVAL;
|
||||||
|
if (tuple->TupleData[0] != 0x04)
|
||||||
|
return -EINVAL;
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
dev->dev_addr[i] = tuple->TupleData[i+2];
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
|
static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
struct smc_cfg_mem *cfg_mem;
|
int rc;
|
||||||
tuple_t *tuple;
|
|
||||||
u_char *buf;
|
|
||||||
int i, rc;
|
|
||||||
|
|
||||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
|
||||||
if (!cfg_mem)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
tuple = &cfg_mem->tuple;
|
|
||||||
buf = cfg_mem->buf;
|
|
||||||
|
|
||||||
tuple->Attributes = TUPLE_RETURN_COMMON;
|
|
||||||
tuple->TupleData = (cisdata_t *)buf;
|
|
||||||
tuple->TupleDataMax = 255;
|
|
||||||
tuple->TupleOffset = 0;
|
|
||||||
|
|
||||||
/* Read the station address from tuple 0x90, subtuple 0x04 */
|
/* Read the station address from tuple 0x90, subtuple 0x04 */
|
||||||
tuple->DesiredTuple = 0x90;
|
if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
|
||||||
i = pcmcia_get_first_tuple(link, tuple);
|
return -1;
|
||||||
while (i == 0) {
|
|
||||||
i = pcmcia_get_tuple_data(link, tuple);
|
|
||||||
if ((i != 0) || (buf[0] == 0x04))
|
|
||||||
break;
|
|
||||||
i = pcmcia_get_next_tuple(link, tuple);
|
|
||||||
}
|
|
||||||
if (i != 0) {
|
|
||||||
rc = -1;
|
|
||||||
goto free_cfg_mem;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
dev->dev_addr[i] = buf[i+2];
|
|
||||||
|
|
||||||
if (((manfid == MANFID_OSITECH) &&
|
if (((manfid == MANFID_OSITECH) &&
|
||||||
(cardid == PRODID_OSITECH_SEVEN)) ||
|
(cardid == PRODID_OSITECH_SEVEN)) ||
|
||||||
@ -836,20 +730,17 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
|
|||||||
(cardid == PRODID_PSION_NET100))) {
|
(cardid == PRODID_PSION_NET100))) {
|
||||||
rc = osi_load_firmware(link);
|
rc = osi_load_firmware(link);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto free_cfg_mem;
|
return rc;
|
||||||
} else if (manfid == MANFID_OSITECH) {
|
} else if (manfid == MANFID_OSITECH) {
|
||||||
/* Make sure both functions are powered up */
|
/* Make sure both functions are powered up */
|
||||||
set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
|
set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
|
||||||
/* Now, turn on the interrupt for both card functions */
|
/* Now, turn on the interrupt for both card functions */
|
||||||
set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
|
set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
|
||||||
DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
|
dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
|
||||||
inw(link->io.BasePort1 + OSITECH_AUI_PWR),
|
inw(link->io.BasePort1 + OSITECH_AUI_PWR),
|
||||||
inw(link->io.BasePort1 + OSITECH_RESET_ISR));
|
inw(link->io.BasePort1 + OSITECH_RESET_ISR));
|
||||||
}
|
}
|
||||||
rc = 0;
|
return 0;
|
||||||
free_cfg_mem:
|
|
||||||
kfree(cfg_mem);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smc91c92_suspend(struct pcmcia_device *link)
|
static int smc91c92_suspend(struct pcmcia_device *link)
|
||||||
@ -959,12 +850,6 @@ static int check_sig(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_EXIT_TEST(ret, svc, label) \
|
|
||||||
if (ret != 0) { \
|
|
||||||
cs_error(link, svc, ret); \
|
|
||||||
goto label; \
|
|
||||||
}
|
|
||||||
|
|
||||||
static int smc91c92_config(struct pcmcia_device *link)
|
static int smc91c92_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
@ -974,7 +859,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||||||
unsigned int ioaddr;
|
unsigned int ioaddr;
|
||||||
u_long mir;
|
u_long mir;
|
||||||
|
|
||||||
DEBUG(0, "smc91c92_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "smc91c92_config\n");
|
||||||
|
|
||||||
smc->manfid = link->manf_id;
|
smc->manfid = link->manf_id;
|
||||||
smc->cardid = link->card_id;
|
smc->cardid = link->card_id;
|
||||||
@ -990,12 +875,15 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||||||
} else {
|
} else {
|
||||||
i = smc_config(link);
|
i = smc_config(link);
|
||||||
}
|
}
|
||||||
CS_EXIT_TEST(i, RequestIO, config_failed);
|
if (i)
|
||||||
|
goto config_failed;
|
||||||
|
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_EXIT_TEST(i, RequestIRQ, config_failed);
|
if (i)
|
||||||
|
goto config_failed;
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
CS_EXIT_TEST(i, RequestConfiguration, config_failed);
|
if (i)
|
||||||
|
goto config_failed;
|
||||||
|
|
||||||
if (smc->manfid == MANFID_MOTOROLA)
|
if (smc->manfid == MANFID_MOTOROLA)
|
||||||
mot_config(link);
|
mot_config(link);
|
||||||
@ -1074,7 +962,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
link->dev_node = &smc->node;
|
link->dev_node = &smc->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if (register_netdev(dev) != 0) {
|
if (register_netdev(dev) != 0) {
|
||||||
printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
|
printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
|
||||||
@ -1100,7 +988,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
if (smc->cfg & CFG_MII_SELECT) {
|
if (smc->cfg & CFG_MII_SELECT) {
|
||||||
if (smc->mii_if.phy_id != -1) {
|
if (smc->mii_if.phy_id != -1) {
|
||||||
DEBUG(0, " MII transceiver at index %d, status %x.\n",
|
dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n",
|
||||||
smc->mii_if.phy_id, j);
|
smc->mii_if.phy_id, j);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_NOTICE " No MII transceivers found!\n");
|
printk(KERN_NOTICE " No MII transceivers found!\n");
|
||||||
@ -1110,7 +998,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
config_undo:
|
config_undo:
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
config_failed: /* CS_EXIT_TEST() calls jump to here... */
|
config_failed:
|
||||||
smc91c92_release(link);
|
smc91c92_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} /* smc91c92_config */
|
} /* smc91c92_config */
|
||||||
@ -1125,7 +1013,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void smc91c92_release(struct pcmcia_device *link)
|
static void smc91c92_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "smc91c92_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "smc91c92_release\n");
|
||||||
if (link->win) {
|
if (link->win) {
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
struct smc_private *smc = netdev_priv(dev);
|
struct smc_private *smc = netdev_priv(dev);
|
||||||
@ -1222,10 +1110,10 @@ static int smc_open(struct net_device *dev)
|
|||||||
struct smc_private *smc = netdev_priv(dev);
|
struct smc_private *smc = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = smc->p_dev;
|
struct pcmcia_device *link = smc->p_dev;
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n",
|
||||||
DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
|
|
||||||
dev->name, dev, inw(dev->base_addr + BANK_SELECT));
|
dev->name, dev, inw(dev->base_addr + BANK_SELECT));
|
||||||
if (pc_debug > 1) smc_dump(dev);
|
#ifdef PCMCIA_DEBUG
|
||||||
|
smc_dump(dev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check that the PCMCIA card is still here. */
|
/* Check that the PCMCIA card is still here. */
|
||||||
@ -1260,7 +1148,7 @@ static int smc_close(struct net_device *dev)
|
|||||||
struct pcmcia_device *link = smc->p_dev;
|
struct pcmcia_device *link = smc->p_dev;
|
||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(0, "%s: smc_close(), status %4.4x.\n",
|
dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n",
|
||||||
dev->name, inw(ioaddr + BANK_SELECT));
|
dev->name, inw(ioaddr + BANK_SELECT));
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
@ -1327,7 +1215,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
|
|||||||
u_char *buf = skb->data;
|
u_char *buf = skb->data;
|
||||||
u_int length = skb->len; /* The chip will pad to ethernet min. */
|
u_int length = skb->len; /* The chip will pad to ethernet min. */
|
||||||
|
|
||||||
DEBUG(2, "%s: Trying to xmit packet of length %d.\n",
|
pr_debug("%s: Trying to xmit packet of length %d.\n",
|
||||||
dev->name, length);
|
dev->name, length);
|
||||||
|
|
||||||
/* send the packet length: +6 for status word, length, and ctl */
|
/* send the packet length: +6 for status word, length, and ctl */
|
||||||
@ -1382,7 +1270,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
|
|||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
DEBUG(2, "%s: smc_start_xmit(length = %d) called,"
|
pr_debug("%s: smc_start_xmit(length = %d) called,"
|
||||||
" status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
|
" status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
|
||||||
|
|
||||||
if (smc->saved_skb) {
|
if (smc->saved_skb) {
|
||||||
@ -1429,7 +1317,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise defer until the Tx-space-allocated interrupt. */
|
/* Otherwise defer until the Tx-space-allocated interrupt. */
|
||||||
DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
|
pr_debug("%s: memory allocation deferred.\n", dev->name);
|
||||||
outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
|
outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
|
||||||
spin_unlock_irqrestore(&smc->lock, flags);
|
spin_unlock_irqrestore(&smc->lock, flags);
|
||||||
|
|
||||||
@ -1494,7 +1382,7 @@ static void smc_eph_irq(struct net_device *dev)
|
|||||||
|
|
||||||
SMC_SELECT_BANK(0);
|
SMC_SELECT_BANK(0);
|
||||||
ephs = inw(ioaddr + EPH);
|
ephs = inw(ioaddr + EPH);
|
||||||
DEBUG(2, "%s: Ethernet protocol handler interrupt, status"
|
pr_debug("%s: Ethernet protocol handler interrupt, status"
|
||||||
" %4.4x.\n", dev->name, ephs);
|
" %4.4x.\n", dev->name, ephs);
|
||||||
/* Could be a counter roll-over warning: update stats. */
|
/* Could be a counter roll-over warning: update stats. */
|
||||||
card_stats = inw(ioaddr + COUNTER);
|
card_stats = inw(ioaddr + COUNTER);
|
||||||
@ -1534,7 +1422,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||||||
|
|
||||||
ioaddr = dev->base_addr;
|
ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
|
pr_debug("%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
|
||||||
irq, ioaddr);
|
irq, ioaddr);
|
||||||
|
|
||||||
spin_lock(&smc->lock);
|
spin_lock(&smc->lock);
|
||||||
@ -1543,7 +1431,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||||||
if ((saved_bank & 0xff00) != 0x3300) {
|
if ((saved_bank & 0xff00) != 0x3300) {
|
||||||
/* The device does not exist -- the card could be off-line, or
|
/* The device does not exist -- the card could be off-line, or
|
||||||
maybe it has been ejected. */
|
maybe it has been ejected. */
|
||||||
DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent"
|
pr_debug("%s: SMC91c92 interrupt %d for non-existent"
|
||||||
"/ejected device.\n", dev->name, irq);
|
"/ejected device.\n", dev->name, irq);
|
||||||
handled = 0;
|
handled = 0;
|
||||||
goto irq_done;
|
goto irq_done;
|
||||||
@ -1557,7 +1445,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||||||
|
|
||||||
do { /* read the status flag, and mask it */
|
do { /* read the status flag, and mask it */
|
||||||
status = inw(ioaddr + INTERRUPT) & 0xff;
|
status = inw(ioaddr + INTERRUPT) & 0xff;
|
||||||
DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
|
pr_debug("%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
|
||||||
status, mask);
|
status, mask);
|
||||||
if ((status & mask) == 0) {
|
if ((status & mask) == 0) {
|
||||||
if (bogus_cnt == INTR_WORK)
|
if (bogus_cnt == INTR_WORK)
|
||||||
@ -1602,7 +1490,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||||||
smc_eph_irq(dev);
|
smc_eph_irq(dev);
|
||||||
} while (--bogus_cnt);
|
} while (--bogus_cnt);
|
||||||
|
|
||||||
DEBUG(3, " Restoring saved registers mask %2.2x bank %4.4x"
|
pr_debug(" Restoring saved registers mask %2.2x bank %4.4x"
|
||||||
" pointer %4.4x.\n", mask, saved_bank, saved_pointer);
|
" pointer %4.4x.\n", mask, saved_bank, saved_pointer);
|
||||||
|
|
||||||
/* restore state register */
|
/* restore state register */
|
||||||
@ -1610,7 +1498,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||||||
outw(saved_pointer, ioaddr + POINTER);
|
outw(saved_pointer, ioaddr + POINTER);
|
||||||
SMC_SELECT_BANK(saved_bank);
|
SMC_SELECT_BANK(saved_bank);
|
||||||
|
|
||||||
DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
|
pr_debug("%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
|
||||||
|
|
||||||
irq_done:
|
irq_done:
|
||||||
|
|
||||||
@ -1661,7 +1549,7 @@ static void smc_rx(struct net_device *dev)
|
|||||||
rx_status = inw(ioaddr + DATA_1);
|
rx_status = inw(ioaddr + DATA_1);
|
||||||
packet_length = inw(ioaddr + DATA_1) & 0x07ff;
|
packet_length = inw(ioaddr + DATA_1) & 0x07ff;
|
||||||
|
|
||||||
DEBUG(2, "%s: Receive status %4.4x length %d.\n",
|
pr_debug("%s: Receive status %4.4x length %d.\n",
|
||||||
dev->name, rx_status, packet_length);
|
dev->name, rx_status, packet_length);
|
||||||
|
|
||||||
if (!(rx_status & RS_ERRORS)) {
|
if (!(rx_status & RS_ERRORS)) {
|
||||||
@ -1672,7 +1560,7 @@ static void smc_rx(struct net_device *dev)
|
|||||||
skb = dev_alloc_skb(packet_length+2);
|
skb = dev_alloc_skb(packet_length+2);
|
||||||
|
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
|
pr_debug("%s: Low memory, packet dropped.\n", dev->name);
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
outw(MC_RELEASE, ioaddr + MMU_CMD);
|
outw(MC_RELEASE, ioaddr + MMU_CMD);
|
||||||
return;
|
return;
|
||||||
@ -1832,7 +1720,7 @@ static void smc_reset(struct net_device *dev)
|
|||||||
struct smc_private *smc = netdev_priv(dev);
|
struct smc_private *smc = netdev_priv(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DEBUG(0, "%s: smc91c92 reset called.\n", dev->name);
|
pr_debug("%s: smc91c92 reset called.\n", dev->name);
|
||||||
|
|
||||||
/* The first interaction must be a write to bring the chip out
|
/* The first interaction must be a write to bring the chip out
|
||||||
of sleep mode. */
|
of sleep mode. */
|
||||||
@ -2149,18 +2037,6 @@ static u32 smc_get_link(struct net_device *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static u32 smc_get_msglevel(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return pc_debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smc_set_msglevel(struct net_device *dev, u32 val)
|
|
||||||
{
|
|
||||||
pc_debug = val;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int smc_nway_reset(struct net_device *dev)
|
static int smc_nway_reset(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct smc_private *smc = netdev_priv(dev);
|
struct smc_private *smc = netdev_priv(dev);
|
||||||
@ -2184,10 +2060,6 @@ static const struct ethtool_ops ethtool_ops = {
|
|||||||
.get_settings = smc_get_settings,
|
.get_settings = smc_get_settings,
|
||||||
.set_settings = smc_set_settings,
|
.set_settings = smc_set_settings,
|
||||||
.get_link = smc_get_link,
|
.get_link = smc_get_link,
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
.get_msglevel = smc_get_msglevel,
|
|
||||||
.set_msglevel = smc_set_msglevel,
|
|
||||||
#endif
|
|
||||||
.nway_reset = smc_nway_reset,
|
.nway_reset = smc_nway_reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -211,20 +211,6 @@ enum xirc_cmd { /* Commands */
|
|||||||
|
|
||||||
static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
|
static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
|
||||||
|
|
||||||
/****************
|
|
||||||
* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
* you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
* left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
* be present but disabled -- but it can then be enabled for specific
|
|
||||||
* modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args)
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: "
|
#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: "
|
||||||
#define KERR_XIRC KERN_ERR "xirc2ps_cs: "
|
#define KERR_XIRC KERN_ERR "xirc2ps_cs: "
|
||||||
@ -359,7 +345,7 @@ static void xirc_tx_timeout(struct net_device *dev);
|
|||||||
static void xirc2ps_tx_timeout_task(struct work_struct *work);
|
static void xirc2ps_tx_timeout_task(struct work_struct *work);
|
||||||
static void set_addresses(struct net_device *dev);
|
static void set_addresses(struct net_device *dev);
|
||||||
static void set_multicast_list(struct net_device *dev);
|
static void set_multicast_list(struct net_device *dev);
|
||||||
static int set_card_type(struct pcmcia_device *link, const void *s);
|
static int set_card_type(struct pcmcia_device *link);
|
||||||
static int do_config(struct net_device *dev, struct ifmap *map);
|
static int do_config(struct net_device *dev, struct ifmap *map);
|
||||||
static int do_open(struct net_device *dev);
|
static int do_open(struct net_device *dev);
|
||||||
static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||||
@ -371,28 +357,6 @@ static void do_powerdown(struct net_device *dev);
|
|||||||
static int do_stop(struct net_device *dev);
|
static int do_stop(struct net_device *dev);
|
||||||
|
|
||||||
/*=============== Helper functions =========================*/
|
/*=============== Helper functions =========================*/
|
||||||
static int
|
|
||||||
first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
|
|
||||||
(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
|
|
||||||
err = pcmcia_parse_tuple(tuple, parse);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
|
|
||||||
(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
|
|
||||||
err = pcmcia_parse_tuple(tuple, parse);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR)
|
#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR)
|
||||||
#define GetByte(reg) ((unsigned)inb(ioaddr + (reg)))
|
#define GetByte(reg) ((unsigned)inb(ioaddr + (reg)))
|
||||||
#define GetWord(reg) ((unsigned)inw(ioaddr + (reg)))
|
#define GetWord(reg) ((unsigned)inw(ioaddr + (reg)))
|
||||||
@ -400,7 +364,7 @@ next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
|||||||
#define PutWord(reg,value) outw((value), ioaddr+(reg))
|
#define PutWord(reg,value) outw((value), ioaddr+(reg))
|
||||||
|
|
||||||
/*====== Functions used for debugging =================================*/
|
/*====== Functions used for debugging =================================*/
|
||||||
#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
|
#if 0 /* reading regs may change system status */
|
||||||
static void
|
static void
|
||||||
PrintRegisters(struct net_device *dev)
|
PrintRegisters(struct net_device *dev)
|
||||||
{
|
{
|
||||||
@ -432,7 +396,7 @@ PrintRegisters(struct net_device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PCMCIA_DEBUG */
|
#endif /* 0 */
|
||||||
|
|
||||||
/*============== MII Management functions ===============*/
|
/*============== MII Management functions ===============*/
|
||||||
|
|
||||||
@ -576,7 +540,7 @@ xirc2ps_probe(struct pcmcia_device *link)
|
|||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "attach()\n");
|
dev_dbg(&link->dev, "attach()\n");
|
||||||
|
|
||||||
/* Allocate the device structure */
|
/* Allocate the device structure */
|
||||||
dev = alloc_etherdev(sizeof(local_info_t));
|
dev = alloc_etherdev(sizeof(local_info_t));
|
||||||
@ -592,7 +556,6 @@ xirc2ps_probe(struct pcmcia_device *link)
|
|||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.ConfigIndex = 1;
|
link->conf.ConfigIndex = 1;
|
||||||
link->irq.Handler = xirc2ps_interrupt;
|
link->irq.Handler = xirc2ps_interrupt;
|
||||||
link->irq.Instance = dev;
|
|
||||||
|
|
||||||
/* Fill in card specific entries */
|
/* Fill in card specific entries */
|
||||||
dev->netdev_ops = &netdev_ops;
|
dev->netdev_ops = &netdev_ops;
|
||||||
@ -615,7 +578,7 @@ xirc2ps_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "detach\n");
|
||||||
|
|
||||||
if (link->dev_node)
|
if (link->dev_node)
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
@ -644,17 +607,25 @@ xirc2ps_detach(struct pcmcia_device *link)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
set_card_type(struct pcmcia_device *link, const void *s)
|
set_card_type(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
local_info_t *local = netdev_priv(dev);
|
local_info_t *local = netdev_priv(dev);
|
||||||
#ifdef PCMCIA_DEBUG
|
u8 *buf;
|
||||||
unsigned cisrev = ((const unsigned char *)s)[2];
|
unsigned int cisrev, mediaid, prodid;
|
||||||
#endif
|
size_t len;
|
||||||
unsigned mediaid= ((const unsigned char *)s)[3];
|
|
||||||
unsigned prodid = ((const unsigned char *)s)[4];
|
|
||||||
|
|
||||||
DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n",
|
len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
|
||||||
|
if (len < 5) {
|
||||||
|
dev_err(&link->dev, "invalid CIS -- sorry\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cisrev = buf[2];
|
||||||
|
mediaid = buf[3];
|
||||||
|
prodid = buf[4];
|
||||||
|
|
||||||
|
dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n",
|
||||||
cisrev, mediaid, prodid);
|
cisrev, mediaid, prodid);
|
||||||
|
|
||||||
local->mohawk = 0;
|
local->mohawk = 0;
|
||||||
@ -761,6 +732,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
struct net_device *dev = priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (tuple->TupleDataLen != 13)
|
||||||
|
return -EINVAL;
|
||||||
|
if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
|
||||||
|
(tuple->TupleData[2] != 6))
|
||||||
|
return -EINVAL;
|
||||||
|
/* another try (James Lehmer's CE2 version 4.1)*/
|
||||||
|
for (i = 2; i < 6; i++)
|
||||||
|
dev->dev_addr[i] = tuple->TupleData[i+2];
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
|
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
|
||||||
* is received, to configure the PCMCIA socket, and to make the
|
* is received, to configure the PCMCIA socket, and to make the
|
||||||
@ -772,33 +763,21 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
local_info_t *local = netdev_priv(dev);
|
local_info_t *local = netdev_priv(dev);
|
||||||
unsigned int ioaddr;
|
unsigned int ioaddr;
|
||||||
tuple_t tuple;
|
int err;
|
||||||
cisparse_t parse;
|
u8 *buf;
|
||||||
int err, i;
|
size_t len;
|
||||||
u_char buf[64];
|
|
||||||
cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
|
|
||||||
|
|
||||||
local->dingo_ccr = NULL;
|
local->dingo_ccr = NULL;
|
||||||
|
|
||||||
DEBUG(0, "config(0x%p)\n", link);
|
dev_dbg(&link->dev, "config\n");
|
||||||
|
|
||||||
/*
|
|
||||||
* This reads the card's CONFIG tuple to find its configuration
|
|
||||||
* registers.
|
|
||||||
*/
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = 64;
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
/* Is this a valid card */
|
/* Is this a valid card */
|
||||||
tuple.DesiredTuple = CISTPL_MANFID;
|
if (link->has_manf_id == 0) {
|
||||||
if ((err=first_tuple(link, &tuple, &parse))) {
|
|
||||||
printk(KNOT_XIRC "manfid not found in CIS\n");
|
printk(KNOT_XIRC "manfid not found in CIS\n");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(parse.manfid.manf) {
|
switch (link->manf_id) {
|
||||||
case MANFID_XIRCOM:
|
case MANFID_XIRCOM:
|
||||||
local->manf_str = "Xircom";
|
local->manf_str = "Xircom";
|
||||||
break;
|
break;
|
||||||
@ -817,65 +796,44 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
|
printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
|
||||||
(unsigned)parse.manfid.manf);
|
(unsigned)link->manf_id);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
DEBUG(0, "found %s card\n", local->manf_str);
|
dev_dbg(&link->dev, "found %s card\n", local->manf_str);
|
||||||
|
|
||||||
if (!set_card_type(link, buf)) {
|
if (!set_card_type(link)) {
|
||||||
printk(KNOT_XIRC "this card is not supported\n");
|
printk(KNOT_XIRC "this card is not supported\n");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the ethernet address from the CIS */
|
/* get the ethernet address from the CIS */
|
||||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
err = pcmcia_get_mac_from_cis(link, dev);
|
||||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
|
||||||
err = next_tuple(link, &tuple, &parse)) {
|
/* not found: try to get the node-id from tuple 0x89 */
|
||||||
/* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
|
if (err) {
|
||||||
* the first one with a length of zero the second correct -
|
len = pcmcia_get_tuple(link, 0x89, &buf);
|
||||||
* so I skip all entries with length 0 */
|
/* data layout looks like tuple 0x22 */
|
||||||
if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID
|
if (buf && len == 8) {
|
||||||
&& ((cistpl_lan_node_id_t *)parse.funce.data)->nb)
|
if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
|
||||||
break;
|
int i;
|
||||||
}
|
for (i = 2; i < 6; i++)
|
||||||
if (err) { /* not found: try to get the node-id from tuple 0x89 */
|
dev->dev_addr[i] = buf[i+2];
|
||||||
tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */
|
} else
|
||||||
if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
|
err = -1;
|
||||||
(err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
|
|
||||||
if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
|
|
||||||
memcpy(&parse, buf, 8);
|
|
||||||
else
|
|
||||||
err = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (err) { /* another try (James Lehmer's CE2 version 4.1)*/
|
|
||||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
|
||||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
|
||||||
err = next_tuple(link, &tuple, &parse)) {
|
|
||||||
if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
|
|
||||||
&& parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
|
|
||||||
buf[1] = 4;
|
|
||||||
memcpy(&parse, buf+1, 8);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
kfree(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KNOT_XIRC "node-id not found in CIS\n");
|
printk(KNOT_XIRC "node-id not found in CIS\n");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
node_id = (cistpl_lan_node_id_t *)parse.funce.data;
|
|
||||||
if (node_id->nb != 6) {
|
|
||||||
printk(KNOT_XIRC "malformed node-id in CIS\n");
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
for (i=0; i < 6; i++)
|
|
||||||
dev->dev_addr[i] = node_id->id[i];
|
|
||||||
|
|
||||||
link->io.IOAddrLines =10;
|
link->io.IOAddrLines =10;
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
link->irq.Attributes = IRQ_HANDLE_PRESENT;
|
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
if (local->modem) {
|
if (local->modem) {
|
||||||
int pass;
|
int pass;
|
||||||
|
|
||||||
@ -916,10 +874,8 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
goto port_found;
|
goto port_found;
|
||||||
}
|
}
|
||||||
link->io.BasePort1 = 0; /* let CS decide */
|
link->io.BasePort1 = 0; /* let CS decide */
|
||||||
if ((err=pcmcia_request_io(link, &link->io))) {
|
if ((err=pcmcia_request_io(link, &link->io)))
|
||||||
cs_error(link, RequestIO, err);
|
|
||||||
goto config_error;
|
goto config_error;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
port_found:
|
port_found:
|
||||||
if (err)
|
if (err)
|
||||||
@ -929,19 +885,15 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
* Now allocate an interrupt line. Note that this does not
|
* Now allocate an interrupt line. Note that this does not
|
||||||
* actually assign a handler to the interrupt.
|
* actually assign a handler to the interrupt.
|
||||||
*/
|
*/
|
||||||
if ((err=pcmcia_request_irq(link, &link->irq))) {
|
if ((err=pcmcia_request_irq(link, &link->irq)))
|
||||||
cs_error(link, RequestIRQ, err);
|
|
||||||
goto config_error;
|
goto config_error;
|
||||||
}
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* This actually configures the PCMCIA socket -- setting up
|
* This actually configures the PCMCIA socket -- setting up
|
||||||
* the I/O windows and the interrupt mapping.
|
* the I/O windows and the interrupt mapping.
|
||||||
*/
|
*/
|
||||||
if ((err=pcmcia_request_configuration(link, &link->conf))) {
|
if ((err=pcmcia_request_configuration(link, &link->conf)))
|
||||||
cs_error(link, RequestConfiguration, err);
|
|
||||||
goto config_error;
|
goto config_error;
|
||||||
}
|
|
||||||
|
|
||||||
if (local->dingo) {
|
if (local->dingo) {
|
||||||
conf_reg_t reg;
|
conf_reg_t reg;
|
||||||
@ -956,17 +908,13 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Offset = CISREG_IOBASE_0;
|
reg.Offset = CISREG_IOBASE_0;
|
||||||
reg.Value = link->io.BasePort2 & 0xff;
|
reg.Value = link->io.BasePort2 & 0xff;
|
||||||
if ((err = pcmcia_access_configuration_register(link, ®))) {
|
if ((err = pcmcia_access_configuration_register(link, ®)))
|
||||||
cs_error(link, AccessConfigurationRegister, err);
|
|
||||||
goto config_error;
|
goto config_error;
|
||||||
}
|
|
||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Offset = CISREG_IOBASE_1;
|
reg.Offset = CISREG_IOBASE_1;
|
||||||
reg.Value = (link->io.BasePort2 >> 8) & 0xff;
|
reg.Value = (link->io.BasePort2 >> 8) & 0xff;
|
||||||
if ((err = pcmcia_access_configuration_register(link, ®))) {
|
if ((err = pcmcia_access_configuration_register(link, ®)))
|
||||||
cs_error(link, AccessConfigurationRegister, err);
|
|
||||||
goto config_error;
|
goto config_error;
|
||||||
}
|
|
||||||
|
|
||||||
/* There is no config entry for the Ethernet part which
|
/* There is no config entry for the Ethernet part which
|
||||||
* is at 0x0800. So we allocate a window into the attribute
|
* is at 0x0800. So we allocate a window into the attribute
|
||||||
@ -975,17 +923,14 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||||
req.Base = req.Size = 0;
|
req.Base = req.Size = 0;
|
||||||
req.AccessSpeed = 0;
|
req.AccessSpeed = 0;
|
||||||
if ((err = pcmcia_request_window(&link, &req, &link->win))) {
|
if ((err = pcmcia_request_window(link, &req, &link->win)))
|
||||||
cs_error(link, RequestWindow, err);
|
|
||||||
goto config_error;
|
goto config_error;
|
||||||
}
|
|
||||||
local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
|
local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
|
||||||
mem.CardOffset = 0x0;
|
mem.CardOffset = 0x0;
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
if ((err = pcmcia_map_mem_page(link->win, &mem))) {
|
if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
|
||||||
cs_error(link, MapMemPage, err);
|
|
||||||
goto config_error;
|
goto config_error;
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup the CCRs; there are no infos in the CIS about the Ethernet
|
/* Setup the CCRs; there are no infos in the CIS about the Ethernet
|
||||||
* part.
|
* part.
|
||||||
@ -1044,7 +989,7 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
do_reset(dev, 1); /* a kludge to make the cem56 work */
|
do_reset(dev, 1); /* a kludge to make the cem56 work */
|
||||||
|
|
||||||
link->dev_node = &local->node;
|
link->dev_node = &local->node;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if ((err=register_netdev(dev))) {
|
if ((err=register_netdev(dev))) {
|
||||||
printk(KNOT_XIRC "register_netdev() failed\n");
|
printk(KNOT_XIRC "register_netdev() failed\n");
|
||||||
@ -1077,7 +1022,7 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||||||
static void
|
static void
|
||||||
xirc2ps_release(struct pcmcia_device *link)
|
xirc2ps_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "release(0x%p)\n", link);
|
dev_dbg(&link->dev, "release\n");
|
||||||
|
|
||||||
if (link->win) {
|
if (link->win) {
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
@ -1144,7 +1089,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
PutByte(XIRCREG_CR, 0);
|
PutByte(XIRCREG_CR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
|
pr_debug("%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
|
||||||
|
|
||||||
saved_page = GetByte(XIRCREG_PR);
|
saved_page = GetByte(XIRCREG_PR);
|
||||||
/* Read the ISR to see whats the cause for the interrupt.
|
/* Read the ISR to see whats the cause for the interrupt.
|
||||||
@ -1154,7 +1099,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
bytes_rcvd = 0;
|
bytes_rcvd = 0;
|
||||||
loop_entry:
|
loop_entry:
|
||||||
if (int_status == 0xff) { /* card may be ejected */
|
if (int_status == 0xff) { /* card may be ejected */
|
||||||
DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq);
|
pr_debug("%s: interrupt %d for dead card\n", dev->name, irq);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
eth_status = GetByte(XIRCREG_ESR);
|
eth_status = GetByte(XIRCREG_ESR);
|
||||||
@ -1167,7 +1112,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
PutByte(XIRCREG40_TXST0, 0);
|
PutByte(XIRCREG40_TXST0, 0);
|
||||||
PutByte(XIRCREG40_TXST1, 0);
|
PutByte(XIRCREG40_TXST1, 0);
|
||||||
|
|
||||||
DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
|
pr_debug("%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
|
||||||
dev->name, int_status, eth_status, rx_status, tx_status);
|
dev->name, int_status, eth_status, rx_status, tx_status);
|
||||||
|
|
||||||
/***** receive section ******/
|
/***** receive section ******/
|
||||||
@ -1178,14 +1123,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
/* too many bytes received during this int, drop the rest of the
|
/* too many bytes received during this int, drop the rest of the
|
||||||
* packets */
|
* packets */
|
||||||
dev->stats.rx_dropped++;
|
dev->stats.rx_dropped++;
|
||||||
DEBUG(2, "%s: RX drop, too much done\n", dev->name);
|
pr_debug("%s: RX drop, too much done\n", dev->name);
|
||||||
} else if (rsr & PktRxOk) {
|
} else if (rsr & PktRxOk) {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
pktlen = GetWord(XIRCREG0_RBC);
|
pktlen = GetWord(XIRCREG0_RBC);
|
||||||
bytes_rcvd += pktlen;
|
bytes_rcvd += pktlen;
|
||||||
|
|
||||||
DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen);
|
pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen);
|
||||||
|
|
||||||
skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
|
skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
@ -1253,19 +1198,19 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
dev->stats.multicast++;
|
dev->stats.multicast++;
|
||||||
}
|
}
|
||||||
} else { /* bad packet */
|
} else { /* bad packet */
|
||||||
DEBUG(5, "rsr=%#02x\n", rsr);
|
pr_debug("rsr=%#02x\n", rsr);
|
||||||
}
|
}
|
||||||
if (rsr & PktTooLong) {
|
if (rsr & PktTooLong) {
|
||||||
dev->stats.rx_frame_errors++;
|
dev->stats.rx_frame_errors++;
|
||||||
DEBUG(3, "%s: Packet too long\n", dev->name);
|
pr_debug("%s: Packet too long\n", dev->name);
|
||||||
}
|
}
|
||||||
if (rsr & CRCErr) {
|
if (rsr & CRCErr) {
|
||||||
dev->stats.rx_crc_errors++;
|
dev->stats.rx_crc_errors++;
|
||||||
DEBUG(3, "%s: CRC error\n", dev->name);
|
pr_debug("%s: CRC error\n", dev->name);
|
||||||
}
|
}
|
||||||
if (rsr & AlignErr) {
|
if (rsr & AlignErr) {
|
||||||
dev->stats.rx_fifo_errors++; /* okay ? */
|
dev->stats.rx_fifo_errors++; /* okay ? */
|
||||||
DEBUG(3, "%s: Alignment error\n", dev->name);
|
pr_debug("%s: Alignment error\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear the received/dropped/error packet */
|
/* clear the received/dropped/error packet */
|
||||||
@ -1277,7 +1222,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
if (rx_status & 0x10) { /* Receive overrun */
|
if (rx_status & 0x10) { /* Receive overrun */
|
||||||
dev->stats.rx_over_errors++;
|
dev->stats.rx_over_errors++;
|
||||||
PutByte(XIRCREG_CR, ClearRxOvrun);
|
PutByte(XIRCREG_CR, ClearRxOvrun);
|
||||||
DEBUG(3, "receive overrun cleared\n");
|
pr_debug("receive overrun cleared\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** transmit section ******/
|
/***** transmit section ******/
|
||||||
@ -1290,13 +1235,13 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
if (nn < n) /* rollover */
|
if (nn < n) /* rollover */
|
||||||
dev->stats.tx_packets += 256 - n;
|
dev->stats.tx_packets += 256 - n;
|
||||||
else if (n == nn) { /* happens sometimes - don't know why */
|
else if (n == nn) { /* happens sometimes - don't know why */
|
||||||
DEBUG(0, "PTR not changed?\n");
|
pr_debug("PTR not changed?\n");
|
||||||
} else
|
} else
|
||||||
dev->stats.tx_packets += lp->last_ptr_value - n;
|
dev->stats.tx_packets += lp->last_ptr_value - n;
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
if (tx_status & 0x0002) { /* Execessive collissions */
|
if (tx_status & 0x0002) { /* Execessive collissions */
|
||||||
DEBUG(0, "tx restarted due to execssive collissions\n");
|
pr_debug("tx restarted due to execssive collissions\n");
|
||||||
PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */
|
PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */
|
||||||
}
|
}
|
||||||
if (tx_status & 0x0040)
|
if (tx_status & 0x0040)
|
||||||
@ -1315,14 +1260,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||||||
maxrx_bytes = 2000;
|
maxrx_bytes = 2000;
|
||||||
else if (maxrx_bytes > 22000)
|
else if (maxrx_bytes > 22000)
|
||||||
maxrx_bytes = 22000;
|
maxrx_bytes = 22000;
|
||||||
DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n",
|
pr_debug("set maxrx=%u (rcvd=%u ticks=%lu)\n",
|
||||||
maxrx_bytes, bytes_rcvd, duration);
|
maxrx_bytes, bytes_rcvd, duration);
|
||||||
} else if (!duration && maxrx_bytes < 22000) {
|
} else if (!duration && maxrx_bytes < 22000) {
|
||||||
/* now much faster */
|
/* now much faster */
|
||||||
maxrx_bytes += 2000;
|
maxrx_bytes += 2000;
|
||||||
if (maxrx_bytes > 22000)
|
if (maxrx_bytes > 22000)
|
||||||
maxrx_bytes = 22000;
|
maxrx_bytes = 22000;
|
||||||
DEBUG(1, "set maxrx=%u\n", maxrx_bytes);
|
pr_debug("set maxrx=%u\n", maxrx_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1372,7 +1317,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
unsigned freespace;
|
unsigned freespace;
|
||||||
unsigned pktlen = skb->len;
|
unsigned pktlen = skb->len;
|
||||||
|
|
||||||
DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n",
|
pr_debug("do_start_xmit(skb=%p, dev=%p) len=%u\n",
|
||||||
skb, dev, pktlen);
|
skb, dev, pktlen);
|
||||||
|
|
||||||
|
|
||||||
@ -1398,7 +1343,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
freespace &= 0x7fff;
|
freespace &= 0x7fff;
|
||||||
/* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */
|
/* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */
|
||||||
okay = pktlen +2 < freespace;
|
okay = pktlen +2 < freespace;
|
||||||
DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
|
pr_debug("%s: avail. tx space=%u%s\n",
|
||||||
dev->name, freespace, okay ? " (okay)":" (not enough)");
|
dev->name, freespace, okay ? " (okay)":" (not enough)");
|
||||||
if (!okay) { /* not enough space */
|
if (!okay) { /* not enough space */
|
||||||
return NETDEV_TX_BUSY; /* upper layer may decide to requeue this packet */
|
return NETDEV_TX_BUSY; /* upper layer may decide to requeue this packet */
|
||||||
@ -1500,7 +1445,7 @@ do_config(struct net_device *dev, struct ifmap *map)
|
|||||||
{
|
{
|
||||||
local_info_t *local = netdev_priv(dev);
|
local_info_t *local = netdev_priv(dev);
|
||||||
|
|
||||||
DEBUG(0, "do_config(%p)\n", dev);
|
pr_debug("do_config(%p)\n", dev);
|
||||||
if (map->port != 255 && map->port != dev->if_port) {
|
if (map->port != 255 && map->port != dev->if_port) {
|
||||||
if (map->port > 4)
|
if (map->port > 4)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1527,7 +1472,7 @@ do_open(struct net_device *dev)
|
|||||||
local_info_t *lp = netdev_priv(dev);
|
local_info_t *lp = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = lp->p_dev;
|
struct pcmcia_device *link = lp->p_dev;
|
||||||
|
|
||||||
DEBUG(0, "do_open(%p)\n", dev);
|
dev_dbg(&link->dev, "do_open(%p)\n", dev);
|
||||||
|
|
||||||
/* Check that the PCMCIA card is still here. */
|
/* Check that the PCMCIA card is still here. */
|
||||||
/* Physical device present signature. */
|
/* Physical device present signature. */
|
||||||
@ -1561,7 +1506,7 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
struct mii_ioctl_data *data = if_mii(rq);
|
struct mii_ioctl_data *data = if_mii(rq);
|
||||||
|
|
||||||
DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
|
pr_debug("%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
|
||||||
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
|
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
|
||||||
data->phy_id, data->reg_num, data->val_in, data->val_out);
|
data->phy_id, data->reg_num, data->val_in, data->val_out);
|
||||||
|
|
||||||
@ -1610,7 +1555,7 @@ do_reset(struct net_device *dev, int full)
|
|||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
unsigned value;
|
unsigned value;
|
||||||
|
|
||||||
DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
|
pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
|
||||||
|
|
||||||
hardreset(dev);
|
hardreset(dev);
|
||||||
PutByte(XIRCREG_CR, SoftReset); /* set */
|
PutByte(XIRCREG_CR, SoftReset); /* set */
|
||||||
@ -1648,8 +1593,8 @@ do_reset(struct net_device *dev, int full)
|
|||||||
}
|
}
|
||||||
msleep(40); /* wait 40 msec to let it complete */
|
msleep(40); /* wait 40 msec to let it complete */
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#if 0
|
||||||
if (pc_debug) {
|
{
|
||||||
SelectPage(0);
|
SelectPage(0);
|
||||||
value = GetByte(XIRCREG_ESR); /* read the ESR */
|
value = GetByte(XIRCREG_ESR); /* read the ESR */
|
||||||
printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
|
printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
|
||||||
@ -1666,7 +1611,7 @@ do_reset(struct net_device *dev, int full)
|
|||||||
value |= DisableLinkPulse;
|
value |= DisableLinkPulse;
|
||||||
PutByte(XIRCREG1_ECR, value);
|
PutByte(XIRCREG1_ECR, value);
|
||||||
#endif
|
#endif
|
||||||
DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value);
|
pr_debug("%s: ECR is: %#02x\n", dev->name, value);
|
||||||
|
|
||||||
SelectPage(0x42);
|
SelectPage(0x42);
|
||||||
PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */
|
PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */
|
||||||
@ -1844,7 +1789,7 @@ do_powerdown(struct net_device *dev)
|
|||||||
|
|
||||||
unsigned int ioaddr = dev->base_addr;
|
unsigned int ioaddr = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(0, "do_powerdown(%p)\n", dev);
|
pr_debug("do_powerdown(%p)\n", dev);
|
||||||
|
|
||||||
SelectPage(4);
|
SelectPage(4);
|
||||||
PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */
|
PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */
|
||||||
@ -1858,7 +1803,7 @@ do_stop(struct net_device *dev)
|
|||||||
local_info_t *lp = netdev_priv(dev);
|
local_info_t *lp = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = lp->p_dev;
|
struct pcmcia_device *link = lp->p_dev;
|
||||||
|
|
||||||
DEBUG(0, "do_stop(%p)\n", dev);
|
dev_dbg(&link->dev, "do_stop(%p)\n", dev);
|
||||||
|
|
||||||
if (!link)
|
if (!link)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -43,21 +43,6 @@
|
|||||||
|
|
||||||
#include "airo.h"
|
#include "airo.h"
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
static char *version = "$Revision: 1.2 $";
|
|
||||||
#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -145,11 +130,10 @@ static int airo_probe(struct pcmcia_device *p_dev)
|
|||||||
{
|
{
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "airo_attach()\n");
|
dev_dbg(&p_dev->dev, "airo_attach()\n");
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
p_dev->irq.Handler = NULL;
|
p_dev->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -184,7 +168,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
|
|||||||
|
|
||||||
static void airo_detach(struct pcmcia_device *link)
|
static void airo_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "airo_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "airo_detach\n");
|
||||||
|
|
||||||
airo_release(link);
|
airo_release(link);
|
||||||
|
|
||||||
@ -204,9 +188,6 @@ static void airo_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int airo_cs_config_check(struct pcmcia_device *p_dev,
|
static int airo_cs_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -275,11 +256,11 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
|
|||||||
req->Base = mem->win[0].host_addr;
|
req->Base = mem->win[0].host_addr;
|
||||||
req->Size = mem->win[0].len;
|
req->Size = mem->win[0].len;
|
||||||
req->AccessSpeed = 0;
|
req->AccessSpeed = 0;
|
||||||
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
|
if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
map.Page = 0;
|
map.Page = 0;
|
||||||
map.CardOffset = mem->win[0].card_addr;
|
map.CardOffset = mem->win[0].card_addr;
|
||||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
/* If we got this far, we're cool! */
|
/* If we got this far, we're cool! */
|
||||||
@ -291,11 +272,11 @@ static int airo_config(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
local_info_t *dev;
|
local_info_t *dev;
|
||||||
win_req_t *req;
|
win_req_t *req;
|
||||||
int last_fn, last_ret;
|
int ret;
|
||||||
|
|
||||||
dev = link->priv;
|
dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "airo_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "airo_config\n");
|
||||||
|
|
||||||
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
||||||
if (!req)
|
if (!req)
|
||||||
@ -315,8 +296,8 @@ static int airo_config(struct pcmcia_device *link)
|
|||||||
* and most client drivers will only use the CIS to fill in
|
* and most client drivers will only use the CIS to fill in
|
||||||
* implementation-defined details.
|
* implementation-defined details.
|
||||||
*/
|
*/
|
||||||
last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
|
ret = pcmcia_loop_config(link, airo_cs_config_check, req);
|
||||||
if (last_ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -324,21 +305,25 @@ static int airo_config(struct pcmcia_device *link)
|
|||||||
handler to the interrupt, unless the 'Handler' member of the
|
handler to the interrupt, unless the 'Handler' member of the
|
||||||
irq structure is initialized.
|
irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This actually configures the PCMCIA socket -- setting up
|
This actually configures the PCMCIA socket -- setting up
|
||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestConfiguration,
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
((local_info_t *)link->priv)->eth_dev =
|
((local_info_t *)link->priv)->eth_dev =
|
||||||
init_airo_card(link->irq.AssignedIRQ,
|
init_airo_card(link->irq.AssignedIRQ,
|
||||||
link->io.BasePort1, 1, &handle_to_dev(link));
|
link->io.BasePort1, 1, &link->dev);
|
||||||
if (!((local_info_t *)link->priv)->eth_dev)
|
if (!((local_info_t *)link->priv)->eth_dev)
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At this point, the dev_node_t structure(s) need to be
|
At this point, the dev_node_t structure(s) need to be
|
||||||
@ -368,8 +353,6 @@ static int airo_config(struct pcmcia_device *link)
|
|||||||
kfree(req);
|
kfree(req);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
airo_release(link);
|
airo_release(link);
|
||||||
kfree(req);
|
kfree(req);
|
||||||
@ -386,7 +369,7 @@ static int airo_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void airo_release(struct pcmcia_device *link)
|
static void airo_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "airo_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "airo_release\n");
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,22 +55,6 @@
|
|||||||
|
|
||||||
#include "atmel.h"
|
#include "atmel.h"
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
static char *version = "$Revision: 1.2 $";
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -155,11 +139,10 @@ static int atmel_probe(struct pcmcia_device *p_dev)
|
|||||||
{
|
{
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "atmel_attach()\n");
|
dev_dbg(&p_dev->dev, "atmel_attach()\n");
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
p_dev->irq.Handler = NULL;
|
p_dev->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -194,7 +177,7 @@ static int atmel_probe(struct pcmcia_device *p_dev)
|
|||||||
|
|
||||||
static void atmel_detach(struct pcmcia_device *link)
|
static void atmel_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "atmel_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "atmel_detach\n");
|
||||||
|
|
||||||
atmel_release(link);
|
atmel_release(link);
|
||||||
|
|
||||||
@ -209,9 +192,6 @@ static void atmel_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
/* Call-back function to interrogate PCMCIA-specific information
|
/* Call-back function to interrogate PCMCIA-specific information
|
||||||
about the current existance of the card */
|
about the current existance of the card */
|
||||||
static int card_present(void *arg)
|
static int card_present(void *arg)
|
||||||
@ -275,13 +255,13 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
|
|||||||
static int atmel_config(struct pcmcia_device *link)
|
static int atmel_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
local_info_t *dev;
|
local_info_t *dev;
|
||||||
int last_fn, last_ret;
|
int ret;
|
||||||
struct pcmcia_device_id *did;
|
struct pcmcia_device_id *did;
|
||||||
|
|
||||||
dev = link->priv;
|
dev = link->priv;
|
||||||
did = dev_get_drvdata(&handle_to_dev(link));
|
did = dev_get_drvdata(&link->dev);
|
||||||
|
|
||||||
DEBUG(0, "atmel_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "atmel_config\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In this loop, we scan the CIS for configuration table entries,
|
In this loop, we scan the CIS for configuration table entries,
|
||||||
@ -303,31 +283,36 @@ static int atmel_config(struct pcmcia_device *link)
|
|||||||
handler to the interrupt, unless the 'Handler' member of the
|
handler to the interrupt, unless the 'Handler' member of the
|
||||||
irq structure is initialized.
|
irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This actually configures the PCMCIA socket -- setting up
|
This actually configures the PCMCIA socket -- setting up
|
||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
if (link->irq.AssignedIRQ == 0) {
|
if (link->irq.AssignedIRQ == 0) {
|
||||||
printk(KERN_ALERT
|
printk(KERN_ALERT
|
||||||
"atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
|
"atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
((local_info_t*)link->priv)->eth_dev =
|
((local_info_t*)link->priv)->eth_dev =
|
||||||
init_atmel_card(link->irq.AssignedIRQ,
|
init_atmel_card(link->irq.AssignedIRQ,
|
||||||
link->io.BasePort1,
|
link->io.BasePort1,
|
||||||
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
|
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
|
||||||
&handle_to_dev(link),
|
&link->dev,
|
||||||
card_present,
|
card_present,
|
||||||
link);
|
link);
|
||||||
if (!((local_info_t*)link->priv)->eth_dev)
|
if (!((local_info_t*)link->priv)->eth_dev)
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -340,8 +325,6 @@ static int atmel_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
atmel_release(link);
|
atmel_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -359,7 +342,7 @@ static void atmel_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
|
struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
|
||||||
|
|
||||||
DEBUG(0, "atmel_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "atmel_release\n");
|
||||||
|
|
||||||
if (dev)
|
if (dev)
|
||||||
stop_atmel_card(dev);
|
stop_atmel_card(dev);
|
||||||
|
@ -65,35 +65,15 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
|
|||||||
struct ssb_bus *ssb;
|
struct ssb_bus *ssb;
|
||||||
win_req_t win;
|
win_req_t win;
|
||||||
memreq_t mem;
|
memreq_t mem;
|
||||||
tuple_t tuple;
|
|
||||||
cisparse_t parse;
|
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
unsigned char buf[64];
|
|
||||||
|
|
||||||
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
|
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
|
||||||
if (!ssb)
|
if (!ssb)
|
||||||
goto out_error;
|
goto out_error;
|
||||||
|
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
res = pcmcia_get_first_tuple(dev, &tuple);
|
|
||||||
if (res != 0)
|
|
||||||
goto err_kfree_ssb;
|
|
||||||
res = pcmcia_get_tuple_data(dev, &tuple);
|
|
||||||
if (res != 0)
|
|
||||||
goto err_kfree_ssb;
|
|
||||||
res = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
if (res != 0)
|
|
||||||
goto err_kfree_ssb;
|
|
||||||
|
|
||||||
dev->conf.ConfigBase = parse.config.base;
|
|
||||||
dev->conf.Present = parse.config.rmask[0];
|
|
||||||
dev->conf.Attributes = CONF_ENABLE_IRQ;
|
dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
dev->conf.IntType = INT_MEMORY_AND_IO;
|
dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -107,20 +87,18 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
|
|||||||
win.Base = 0;
|
win.Base = 0;
|
||||||
win.Size = SSB_CORE_SIZE;
|
win.Size = SSB_CORE_SIZE;
|
||||||
win.AccessSpeed = 250;
|
win.AccessSpeed = 250;
|
||||||
res = pcmcia_request_window(&dev, &win, &dev->win);
|
res = pcmcia_request_window(dev, &win, &dev->win);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
goto err_kfree_ssb;
|
goto err_kfree_ssb;
|
||||||
|
|
||||||
mem.CardOffset = 0;
|
mem.CardOffset = 0;
|
||||||
mem.Page = 0;
|
mem.Page = 0;
|
||||||
res = pcmcia_map_mem_page(dev->win, &mem);
|
res = pcmcia_map_mem_page(dev, dev->win, &mem);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
goto err_disable;
|
goto err_disable;
|
||||||
|
|
||||||
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
dev->irq.Handler = NULL; /* The handler is registered later. */
|
dev->irq.Handler = NULL; /* The handler is registered later. */
|
||||||
dev->irq.Instance = NULL;
|
|
||||||
res = pcmcia_request_irq(dev, &dev->irq);
|
res = pcmcia_request_irq(dev, &dev->irq);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
goto err_disable;
|
goto err_disable;
|
||||||
|
@ -274,9 +274,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||||||
conf_reg_t reg;
|
conf_reg_t reg;
|
||||||
struct hostap_interface *iface = netdev_priv(dev);
|
struct hostap_interface *iface = netdev_priv(dev);
|
||||||
local_info_t *local = iface->local;
|
local_info_t *local = iface->local;
|
||||||
tuple_t tuple;
|
|
||||||
cisparse_t *parse = NULL;
|
|
||||||
u_char buf[64];
|
|
||||||
struct hostap_cs_priv *hw_priv = local->hw_priv;
|
struct hostap_cs_priv *hw_priv = local->hw_priv;
|
||||||
|
|
||||||
if (hw_priv->link->io.NumPorts1 < 0x42) {
|
if (hw_priv->link->io.NumPorts1 < 0x42) {
|
||||||
@ -285,28 +282,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
|
|
||||||
if (parse == NULL) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
|
if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
|
||||||
/* No SanDisk manfid found */
|
/* No SanDisk manfid found */
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
|
if (hw_priv->link->socket->functions < 2) {
|
||||||
if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
|
|
||||||
pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
|
|
||||||
pcmcia_parse_tuple(&tuple, parse) ||
|
|
||||||
parse->longlink_mfc.nfn < 2) {
|
|
||||||
/* No multi-function links found */
|
/* No multi-function links found */
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto done;
|
goto done;
|
||||||
@ -354,7 +336,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||||||
udelay(10);
|
udelay(10);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
kfree(parse);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,10 +510,6 @@ static void prism2_detach(struct pcmcia_device *link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/* run after a CARD_INSERTION event is received to configure the PCMCIA
|
/* run after a CARD_INSERTION event is received to configure the PCMCIA
|
||||||
* socket and make the device available to the system */
|
* socket and make the device available to the system */
|
||||||
|
|
||||||
@ -624,7 +601,6 @@ static int prism2_config(struct pcmcia_device *link)
|
|||||||
struct hostap_interface *iface;
|
struct hostap_interface *iface;
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
int last_fn, last_ret;
|
|
||||||
struct hostap_cs_priv *hw_priv;
|
struct hostap_cs_priv *hw_priv;
|
||||||
|
|
||||||
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
|
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
|
||||||
@ -636,19 +612,18 @@ static int prism2_config(struct pcmcia_device *link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Look for an appropriate configuration table entry in the CIS */
|
/* Look for an appropriate configuration table entry in the CIS */
|
||||||
last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
|
ret = pcmcia_loop_config(link, prism2_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret) {
|
||||||
if (!ignore_cis_vcc)
|
if (!ignore_cis_vcc)
|
||||||
printk(KERN_ERR "GetNextTuple(): No matching "
|
printk(KERN_ERR "GetNextTuple(): No matching "
|
||||||
"CIS configuration. Maybe you need the "
|
"CIS configuration. Maybe you need the "
|
||||||
"ignore_cis_vcc=1 parameter.\n");
|
"ignore_cis_vcc=1 parameter.\n");
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to allocate net_device before requesting IRQ handler */
|
/* Need to allocate net_device before requesting IRQ handler */
|
||||||
dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
|
dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
|
||||||
&handle_to_dev(link));
|
&link->dev);
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
link->priv = dev;
|
link->priv = dev;
|
||||||
@ -666,13 +641,11 @@ static int prism2_config(struct pcmcia_device *link)
|
|||||||
* irq structure is initialized.
|
* irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
IRQ_HANDLE_PRESENT;
|
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = prism2_interrupt;
|
link->irq.Handler = prism2_interrupt;
|
||||||
link->irq.Instance = dev;
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestIRQ,
|
if (ret)
|
||||||
pcmcia_request_irq(link, &link->irq));
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -680,8 +653,9 @@ static int prism2_config(struct pcmcia_device *link)
|
|||||||
* the I/O windows and the interrupt mapping, and putting the
|
* the I/O windows and the interrupt mapping, and putting the
|
||||||
* card and host interface into "Memory and IO" mode.
|
* card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestConfiguration,
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
@ -714,9 +688,6 @@ static int prism2_config(struct pcmcia_device *link)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
kfree(hw_priv);
|
kfree(hw_priv);
|
||||||
prism2_release((u_long)link);
|
prism2_release((u_long)link);
|
||||||
|
@ -590,7 +590,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
|
|||||||
|
|
||||||
/* TODO: make firmware file configurable */
|
/* TODO: make firmware file configurable */
|
||||||
ret = request_firmware(&fw, "libertas_cs_helper.fw",
|
ret = request_firmware(&fw, "libertas_cs_helper.fw",
|
||||||
&handle_to_dev(card->p_dev));
|
&card->p_dev->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
lbs_pr_err("can't load helper firmware\n");
|
lbs_pr_err("can't load helper firmware\n");
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
@ -663,7 +663,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
|
|||||||
|
|
||||||
/* TODO: make firmware file configurable */
|
/* TODO: make firmware file configurable */
|
||||||
ret = request_firmware(&fw, "libertas_cs.fw",
|
ret = request_firmware(&fw, "libertas_cs.fw",
|
||||||
&handle_to_dev(card->p_dev));
|
&card->p_dev->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
lbs_pr_err("can't load firmware\n");
|
lbs_pr_err("can't load firmware\n");
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
@ -793,18 +793,37 @@ static void if_cs_release(struct pcmcia_device *p_dev)
|
|||||||
* configure the card at this point -- we wait until we receive a card
|
* configure the card at this point -- we wait until we receive a card
|
||||||
* insertion event.
|
* insertion event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int if_cs_ioprobe(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
p_dev->io.BasePort1 = cfg->io.win[0].base;
|
||||||
|
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||||
|
|
||||||
|
/* Do we need to allocate an interrupt? */
|
||||||
|
if (cfg->irq.IRQInfo1)
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||||
|
|
||||||
|
/* IO window settings */
|
||||||
|
if (cfg->io.nwin != 1) {
|
||||||
|
lbs_pr_err("wrong CIS (check number of IO windows)\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This reserves IO space but doesn't actually enable it */
|
||||||
|
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||||
|
}
|
||||||
|
|
||||||
static int if_cs_probe(struct pcmcia_device *p_dev)
|
static int if_cs_probe(struct pcmcia_device *p_dev)
|
||||||
{
|
{
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
unsigned int prod_id;
|
unsigned int prod_id;
|
||||||
struct lbs_private *priv;
|
struct lbs_private *priv;
|
||||||
struct if_cs_card *card;
|
struct if_cs_card *card;
|
||||||
/* CIS parsing */
|
|
||||||
tuple_t tuple;
|
|
||||||
cisparse_t parse;
|
|
||||||
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
|
|
||||||
cistpl_io_t *io = &cfg->io;
|
|
||||||
u_char buf[64];
|
|
||||||
|
|
||||||
lbs_deb_enter(LBS_DEB_CS);
|
lbs_deb_enter(LBS_DEB_CS);
|
||||||
|
|
||||||
@ -818,48 +837,15 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
|
|||||||
|
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
p_dev->irq.Handler = NULL;
|
p_dev->irq.Handler = NULL;
|
||||||
p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
p_dev->conf.Attributes = 0;
|
p_dev->conf.Attributes = 0;
|
||||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
tuple.Attributes = 0;
|
if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
|
||||||
tuple.TupleData = buf;
|
lbs_pr_err("error in pcmcia_loop_config\n");
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
|
|
||||||
(ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
|
|
||||||
(ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
|
|
||||||
{
|
|
||||||
lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
|
|
||||||
goto out1;
|
goto out1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_dev->conf.ConfigIndex = cfg->index;
|
|
||||||
|
|
||||||
/* Do we need to allocate an interrupt? */
|
|
||||||
if (cfg->irq.IRQInfo1) {
|
|
||||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IO window settings */
|
|
||||||
if (cfg->io.nwin != 1) {
|
|
||||||
lbs_pr_err("wrong CIS (check number of IO windows)\n");
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto out1;
|
|
||||||
}
|
|
||||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
p_dev->io.BasePort1 = io->win[0].base;
|
|
||||||
p_dev->io.NumPorts1 = io->win[0].len;
|
|
||||||
|
|
||||||
/* This reserves IO space but doesn't actually enable it */
|
|
||||||
ret = pcmcia_request_io(p_dev, &p_dev->io);
|
|
||||||
if (ret) {
|
|
||||||
lbs_pr_err("error in pcmcia_request_io\n");
|
|
||||||
goto out1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate an interrupt line. Note that this does not assign
|
* Allocate an interrupt line. Note that this does not assign
|
||||||
|
@ -145,23 +145,6 @@ static const unsigned int txConfEUD = 0x10; /* Enable Uni-Data packets */
|
|||||||
static const unsigned int txConfKey = 0x02; /* Scramble data packets */
|
static const unsigned int txConfKey = 0x02; /* Scramble data packets */
|
||||||
static const unsigned int txConfLoop = 0x01; /* Loopback mode */
|
static const unsigned int txConfLoop = 0x01; /* Loopback mode */
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -383,7 +366,7 @@ static int netwave_probe(struct pcmcia_device *link)
|
|||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
netwave_private *priv;
|
netwave_private *priv;
|
||||||
|
|
||||||
DEBUG(0, "netwave_attach()\n");
|
dev_dbg(&link->dev, "netwave_attach()\n");
|
||||||
|
|
||||||
/* Initialize the struct pcmcia_device structure */
|
/* Initialize the struct pcmcia_device structure */
|
||||||
dev = alloc_etherdev(sizeof(netwave_private));
|
dev = alloc_etherdev(sizeof(netwave_private));
|
||||||
@ -401,8 +384,7 @@ static int netwave_probe(struct pcmcia_device *link)
|
|||||||
link->io.IOAddrLines = 5;
|
link->io.IOAddrLines = 5;
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = &netwave_interrupt;
|
link->irq.Handler = &netwave_interrupt;
|
||||||
|
|
||||||
/* General socket configuration */
|
/* General socket configuration */
|
||||||
@ -421,8 +403,6 @@ static int netwave_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
dev->watchdog_timeo = TX_TIMEOUT;
|
dev->watchdog_timeo = TX_TIMEOUT;
|
||||||
|
|
||||||
link->irq.Instance = dev;
|
|
||||||
|
|
||||||
return netwave_pcmcia_config( link);
|
return netwave_pcmcia_config( link);
|
||||||
} /* netwave_attach */
|
} /* netwave_attach */
|
||||||
|
|
||||||
@ -438,7 +418,7 @@ static void netwave_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "netwave_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "netwave_detach\n");
|
||||||
|
|
||||||
netwave_release(link);
|
netwave_release(link);
|
||||||
|
|
||||||
@ -725,18 +705,15 @@ static const struct iw_handler_def netwave_handler_def =
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
netwave_private *priv = netdev_priv(dev);
|
netwave_private *priv = netdev_priv(dev);
|
||||||
int i, j, last_ret, last_fn;
|
int i, j, ret;
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
memreq_t mem;
|
memreq_t mem;
|
||||||
u_char __iomem *ramBase = NULL;
|
u_char __iomem *ramBase = NULL;
|
||||||
|
|
||||||
DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "netwave_pcmcia_config\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try allocating IO ports. This tries a few fixed addresses.
|
* Try allocating IO ports. This tries a few fixed addresses.
|
||||||
@ -749,22 +726,24 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
|||||||
if (i == 0)
|
if (i == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIO, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now allocate an interrupt line. Note that this does not
|
* Now allocate an interrupt line. Note that this does not
|
||||||
* actually assign a handler to the interrupt.
|
* actually assign a handler to the interrupt.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This actually configures the PCMCIA socket -- setting up
|
* This actually configures the PCMCIA socket -- setting up
|
||||||
* the I/O windows and the interrupt mapping.
|
* the I/O windows and the interrupt mapping.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a 32K memory window. Note that the struct pcmcia_device
|
* Allocate a 32K memory window. Note that the struct pcmcia_device
|
||||||
@ -772,14 +751,18 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
|||||||
* device needs several windows, you'll need to keep track of
|
* device needs several windows, you'll need to keep track of
|
||||||
* the handles in your private data structure, dev->priv.
|
* the handles in your private data structure, dev->priv.
|
||||||
*/
|
*/
|
||||||
DEBUG(1, "Setting mem speed of %d\n", mem_speed);
|
dev_dbg(&link->dev, "Setting mem speed of %d\n", mem_speed);
|
||||||
|
|
||||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
|
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
|
||||||
req.Base = 0; req.Size = 0x8000;
|
req.Base = 0; req.Size = 0x8000;
|
||||||
req.AccessSpeed = mem_speed;
|
req.AccessSpeed = mem_speed;
|
||||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
ret = pcmcia_request_window(link, &req, &link->win);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
mem.CardOffset = 0x20000; mem.Page = 0;
|
mem.CardOffset = 0x20000; mem.Page = 0;
|
||||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
|
ret = pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* Store base address of the common window frame */
|
/* Store base address of the common window frame */
|
||||||
ramBase = ioremap(req.Base, 0x8000);
|
ramBase = ioremap(req.Base, 0x8000);
|
||||||
@ -787,7 +770,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
|||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
|
|
||||||
if (register_netdev(dev) != 0) {
|
if (register_netdev(dev) != 0) {
|
||||||
printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
|
printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
|
||||||
@ -818,8 +801,6 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
|
|||||||
get_uint16(ramBase + NETWAVE_EREG_ARW+2));
|
get_uint16(ramBase + NETWAVE_EREG_ARW+2));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
netwave_release(link);
|
netwave_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -837,7 +818,7 @@ static void netwave_release(struct pcmcia_device *link)
|
|||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
netwave_private *priv = netdev_priv(dev);
|
netwave_private *priv = netdev_priv(dev);
|
||||||
|
|
||||||
DEBUG(0, "netwave_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "netwave_release\n");
|
||||||
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
if (link->win)
|
if (link->win)
|
||||||
@ -892,7 +873,7 @@ static void netwave_reset(struct net_device *dev) {
|
|||||||
u_char __iomem *ramBase = priv->ramBase;
|
u_char __iomem *ramBase = priv->ramBase;
|
||||||
unsigned int iobase = dev->base_addr;
|
unsigned int iobase = dev->base_addr;
|
||||||
|
|
||||||
DEBUG(0, "netwave_reset: Done with hardware reset\n");
|
pr_debug("netwave_reset: Done with hardware reset\n");
|
||||||
|
|
||||||
priv->timeoutCounter = 0;
|
priv->timeoutCounter = 0;
|
||||||
|
|
||||||
@ -988,7 +969,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
|
|||||||
|
|
||||||
dev->stats.tx_bytes += len;
|
dev->stats.tx_bytes += len;
|
||||||
|
|
||||||
DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
|
pr_debug("Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
|
||||||
readb(ramBase + NETWAVE_EREG_SPCQ),
|
readb(ramBase + NETWAVE_EREG_SPCQ),
|
||||||
readb(ramBase + NETWAVE_EREG_SPU),
|
readb(ramBase + NETWAVE_EREG_SPU),
|
||||||
readb(ramBase + NETWAVE_EREG_LIF),
|
readb(ramBase + NETWAVE_EREG_LIF),
|
||||||
@ -1000,7 +981,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
|
|||||||
MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
|
MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
|
||||||
DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
|
DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
|
||||||
|
|
||||||
DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
|
pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n",
|
||||||
TxFreeList, MaxData, DataOffset);
|
TxFreeList, MaxData, DataOffset);
|
||||||
|
|
||||||
/* Copy packet to the adapter fragment buffers */
|
/* Copy packet to the adapter fragment buffers */
|
||||||
@ -1088,7 +1069,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
|
|||||||
status = inb(iobase + NETWAVE_REG_ASR);
|
status = inb(iobase + NETWAVE_REG_ASR);
|
||||||
|
|
||||||
if (!pcmcia_dev_present(link)) {
|
if (!pcmcia_dev_present(link)) {
|
||||||
DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
|
pr_debug("netwave_interrupt: Interrupt with status 0x%x "
|
||||||
"from removed or suspended card!\n", status);
|
"from removed or suspended card!\n", status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1132,7 +1113,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
|
|||||||
int txStatus;
|
int txStatus;
|
||||||
|
|
||||||
txStatus = readb(ramBase + NETWAVE_EREG_TSER);
|
txStatus = readb(ramBase + NETWAVE_EREG_TSER);
|
||||||
DEBUG(3, "Transmit done. TSER = %x id %x\n",
|
pr_debug("Transmit done. TSER = %x id %x\n",
|
||||||
txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
|
txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
|
||||||
|
|
||||||
if (txStatus & 0x20) {
|
if (txStatus & 0x20) {
|
||||||
@ -1156,7 +1137,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
|
|||||||
* TxGU and TxNOAP is set. (Those are the only ones
|
* TxGU and TxNOAP is set. (Those are the only ones
|
||||||
* to set TxErr).
|
* to set TxErr).
|
||||||
*/
|
*/
|
||||||
DEBUG(3, "netwave_interrupt: TxDN with error status %x\n",
|
pr_debug("netwave_interrupt: TxDN with error status %x\n",
|
||||||
txStatus);
|
txStatus);
|
||||||
|
|
||||||
/* Clear out TxGU, TxNOAP, TxErr and TxTrys */
|
/* Clear out TxGU, TxNOAP, TxErr and TxTrys */
|
||||||
@ -1164,7 +1145,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
|
|||||||
writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
|
writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
|
||||||
++dev->stats.tx_errors;
|
++dev->stats.tx_errors;
|
||||||
}
|
}
|
||||||
DEBUG(3, "New status is TSER %x ASR %x\n",
|
pr_debug("New status is TSER %x ASR %x\n",
|
||||||
readb(ramBase + NETWAVE_EREG_TSER),
|
readb(ramBase + NETWAVE_EREG_TSER),
|
||||||
inb(iobase + NETWAVE_REG_ASR));
|
inb(iobase + NETWAVE_REG_ASR));
|
||||||
|
|
||||||
@ -1172,7 +1153,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
|
|||||||
}
|
}
|
||||||
/* TxBA, this would trigger on all error packets received */
|
/* TxBA, this would trigger on all error packets received */
|
||||||
/* if (status & 0x01) {
|
/* if (status & 0x01) {
|
||||||
DEBUG(4, "Transmit buffers available, %x\n", status);
|
pr_debug("Transmit buffers available, %x\n", status);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@ -1190,7 +1171,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
|
|||||||
*/
|
*/
|
||||||
static void netwave_watchdog(struct net_device *dev) {
|
static void netwave_watchdog(struct net_device *dev) {
|
||||||
|
|
||||||
DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
|
pr_debug("%s: netwave_watchdog: watchdog timer expired\n", dev->name);
|
||||||
netwave_reset(dev);
|
netwave_reset(dev);
|
||||||
dev->trans_start = jiffies;
|
dev->trans_start = jiffies;
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
@ -1211,7 +1192,7 @@ static int netwave_rx(struct net_device *dev)
|
|||||||
int i;
|
int i;
|
||||||
u_char *ptr;
|
u_char *ptr;
|
||||||
|
|
||||||
DEBUG(3, "xinw_rx: Receiving ... \n");
|
pr_debug("xinw_rx: Receiving ... \n");
|
||||||
|
|
||||||
/* Receive max 10 packets for now. */
|
/* Receive max 10 packets for now. */
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
@ -1237,7 +1218,7 @@ static int netwave_rx(struct net_device *dev)
|
|||||||
|
|
||||||
skb = dev_alloc_skb(rcvLen+5);
|
skb = dev_alloc_skb(rcvLen+5);
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
|
pr_debug("netwave_rx: Could not allocate an sk_buff of "
|
||||||
"length %d\n", rcvLen);
|
"length %d\n", rcvLen);
|
||||||
++dev->stats.rx_dropped;
|
++dev->stats.rx_dropped;
|
||||||
/* Tell the adapter to skip the packet */
|
/* Tell the adapter to skip the packet */
|
||||||
@ -1279,7 +1260,7 @@ static int netwave_rx(struct net_device *dev)
|
|||||||
wait_WOC(iobase);
|
wait_WOC(iobase);
|
||||||
writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
|
writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
|
||||||
writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
|
writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
|
||||||
DEBUG(3, "Packet reception ok\n");
|
pr_debug("Packet reception ok\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1288,7 +1269,7 @@ static int netwave_open(struct net_device *dev) {
|
|||||||
netwave_private *priv = netdev_priv(dev);
|
netwave_private *priv = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = priv->p_dev;
|
struct pcmcia_device *link = priv->p_dev;
|
||||||
|
|
||||||
DEBUG(1, "netwave_open: starting.\n");
|
dev_dbg(&link->dev, "netwave_open: starting.\n");
|
||||||
|
|
||||||
if (!pcmcia_dev_present(link))
|
if (!pcmcia_dev_present(link))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -1305,7 +1286,7 @@ static int netwave_close(struct net_device *dev) {
|
|||||||
netwave_private *priv = netdev_priv(dev);
|
netwave_private *priv = netdev_priv(dev);
|
||||||
struct pcmcia_device *link = priv->p_dev;
|
struct pcmcia_device *link = priv->p_dev;
|
||||||
|
|
||||||
DEBUG(1, "netwave_close: finishing.\n");
|
dev_dbg(&link->dev, "netwave_close: finishing.\n");
|
||||||
|
|
||||||
link->open--;
|
link->open--;
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
@ -1358,11 +1339,11 @@ static void set_multicast_list(struct net_device *dev)
|
|||||||
u_char rcvMode = 0;
|
u_char rcvMode = 0;
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
#ifdef PCMCIA_DEBUG
|
||||||
if (pc_debug > 2) {
|
{
|
||||||
static int old;
|
xstatic int old;
|
||||||
if (old != dev->mc_count) {
|
if (old != dev->mc_count) {
|
||||||
old = dev->mc_count;
|
old = dev->mc_count;
|
||||||
DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
|
pr_debug("%s: setting Rx mode to %d addresses.\n",
|
||||||
dev->name, dev->mc_count);
|
dev->name, dev->mc_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
|
|||||||
struct orinoco_private *priv;
|
struct orinoco_private *priv;
|
||||||
struct orinoco_pccard *card;
|
struct orinoco_pccard *card;
|
||||||
|
|
||||||
priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
|
priv = alloc_orinocodev(sizeof(*card), &link->dev,
|
||||||
orinoco_cs_hard_reset, NULL);
|
orinoco_cs_hard_reset, NULL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -120,10 +120,8 @@ orinoco_cs_probe(struct pcmcia_device *link)
|
|||||||
link->priv = priv;
|
link->priv = priv;
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = orinoco_interrupt;
|
link->irq.Handler = orinoco_interrupt;
|
||||||
link->irq.Instance = priv;
|
|
||||||
|
|
||||||
/* General socket configuration defaults can go here. In this
|
/* General socket configuration defaults can go here. In this
|
||||||
* client, we assume very little, and rely on the CIS for
|
* client, we assume very little, and rely on the CIS for
|
||||||
@ -160,12 +158,6 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
|
|||||||
* device available to the system.
|
* device available to the system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) do { \
|
|
||||||
last_fn = (fn); \
|
|
||||||
if ((last_ret = (ret)) != 0) \
|
|
||||||
goto cs_failed; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
|
static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -240,7 +232,7 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||||||
struct orinoco_private *priv = link->priv;
|
struct orinoco_private *priv = link->priv;
|
||||||
struct orinoco_pccard *card = priv->card;
|
struct orinoco_pccard *card = priv->card;
|
||||||
hermes_t *hw = &priv->hw;
|
hermes_t *hw = &priv->hw;
|
||||||
int last_fn, last_ret;
|
int ret;
|
||||||
void __iomem *mem;
|
void __iomem *mem;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -257,13 +249,12 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||||||
* and most client drivers will only use the CIS to fill in
|
* and most client drivers will only use the CIS to fill in
|
||||||
* implementation-defined details.
|
* implementation-defined details.
|
||||||
*/
|
*/
|
||||||
last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
|
ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret) {
|
||||||
if (!ignore_cis_vcc)
|
if (!ignore_cis_vcc)
|
||||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||||
"CIS configuration. Maybe you need the "
|
"CIS configuration. Maybe you need the "
|
||||||
"ignore_cis_vcc=1 parameter.\n");
|
"ignore_cis_vcc=1 parameter.\n");
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,14 +263,16 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||||||
* a handler to the interrupt, unless the 'Handler' member of
|
* a handler to the interrupt, unless the 'Handler' member of
|
||||||
* the irq structure is initialized.
|
* the irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* We initialize the hermes structure before completing PCMCIA
|
/* We initialize the hermes structure before completing PCMCIA
|
||||||
* configuration just in case the interrupt handler gets
|
* configuration just in case the interrupt handler gets
|
||||||
* called. */
|
* called. */
|
||||||
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
|
|
||||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||||
|
|
||||||
@ -288,8 +281,9 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||||||
* the I/O windows and the interrupt mapping, and putting the
|
* the I/O windows and the interrupt mapping, and putting the
|
||||||
* card and host interface into "Memory and IO" mode.
|
* card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestConfiguration,
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* Ok, we have the configuration, prepare to register the netdev */
|
/* Ok, we have the configuration, prepare to register the netdev */
|
||||||
card->node.major = card->node.minor = 0;
|
card->node.major = card->node.minor = 0;
|
||||||
@ -315,9 +309,6 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||||||
* net_device has been registered */
|
* net_device has been registered */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
orinoco_cs_release(link);
|
orinoco_cs_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -73,9 +73,6 @@ static void spectrum_cs_release(struct pcmcia_device *link);
|
|||||||
#define HCR_MEM16 0x10 /* memory width bit, should be preserved */
|
#define HCR_MEM16 0x10 /* memory width bit, should be preserved */
|
||||||
|
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the card using configuration registers COR and CCSR.
|
* Reset the card using configuration registers COR and CCSR.
|
||||||
* If IDLE is 1, stop the firmware, so that it can be safely rewritten.
|
* If IDLE is 1, stop the firmware, so that it can be safely rewritten.
|
||||||
@ -83,7 +80,7 @@ static void spectrum_cs_release(struct pcmcia_device *link);
|
|||||||
static int
|
static int
|
||||||
spectrum_reset(struct pcmcia_device *link, int idle)
|
spectrum_reset(struct pcmcia_device *link, int idle)
|
||||||
{
|
{
|
||||||
int last_ret, last_fn;
|
int ret;
|
||||||
conf_reg_t reg;
|
conf_reg_t reg;
|
||||||
u_int save_cor;
|
u_int save_cor;
|
||||||
|
|
||||||
@ -95,23 +92,26 @@ spectrum_reset(struct pcmcia_device *link, int idle)
|
|||||||
reg.Function = 0;
|
reg.Function = 0;
|
||||||
reg.Action = CS_READ;
|
reg.Action = CS_READ;
|
||||||
reg.Offset = CISREG_COR;
|
reg.Offset = CISREG_COR;
|
||||||
CS_CHECK(AccessConfigurationRegister,
|
ret = pcmcia_access_configuration_register(link, ®);
|
||||||
pcmcia_access_configuration_register(link, ®));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
save_cor = reg.Value;
|
save_cor = reg.Value;
|
||||||
|
|
||||||
/* Soft-Reset card */
|
/* Soft-Reset card */
|
||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Offset = CISREG_COR;
|
reg.Offset = CISREG_COR;
|
||||||
reg.Value = (save_cor | COR_SOFT_RESET);
|
reg.Value = (save_cor | COR_SOFT_RESET);
|
||||||
CS_CHECK(AccessConfigurationRegister,
|
ret = pcmcia_access_configuration_register(link, ®);
|
||||||
pcmcia_access_configuration_register(link, ®));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
udelay(1000);
|
udelay(1000);
|
||||||
|
|
||||||
/* Read CCSR */
|
/* Read CCSR */
|
||||||
reg.Action = CS_READ;
|
reg.Action = CS_READ;
|
||||||
reg.Offset = CISREG_CCSR;
|
reg.Offset = CISREG_CCSR;
|
||||||
CS_CHECK(AccessConfigurationRegister,
|
ret = pcmcia_access_configuration_register(link, ®);
|
||||||
pcmcia_access_configuration_register(link, ®));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start or stop the firmware. Memory width bit should be
|
* Start or stop the firmware. Memory width bit should be
|
||||||
@ -120,21 +120,22 @@ spectrum_reset(struct pcmcia_device *link, int idle)
|
|||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Offset = CISREG_CCSR;
|
reg.Offset = CISREG_CCSR;
|
||||||
reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
|
reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
|
||||||
CS_CHECK(AccessConfigurationRegister,
|
ret = pcmcia_access_configuration_register(link, ®);
|
||||||
pcmcia_access_configuration_register(link, ®));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
udelay(1000);
|
udelay(1000);
|
||||||
|
|
||||||
/* Restore original COR configuration index */
|
/* Restore original COR configuration index */
|
||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Offset = CISREG_COR;
|
reg.Offset = CISREG_COR;
|
||||||
reg.Value = (save_cor & ~COR_SOFT_RESET);
|
reg.Value = (save_cor & ~COR_SOFT_RESET);
|
||||||
CS_CHECK(AccessConfigurationRegister,
|
ret = pcmcia_access_configuration_register(link, ®);
|
||||||
pcmcia_access_configuration_register(link, ®));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
udelay(1000);
|
udelay(1000);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +182,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
|
|||||||
struct orinoco_private *priv;
|
struct orinoco_private *priv;
|
||||||
struct orinoco_pccard *card;
|
struct orinoco_pccard *card;
|
||||||
|
|
||||||
priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
|
priv = alloc_orinocodev(sizeof(*card), &link->dev,
|
||||||
spectrum_cs_hard_reset,
|
spectrum_cs_hard_reset,
|
||||||
spectrum_cs_stop_firmware);
|
spectrum_cs_stop_firmware);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
@ -193,10 +194,8 @@ spectrum_cs_probe(struct pcmcia_device *link)
|
|||||||
link->priv = priv;
|
link->priv = priv;
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = orinoco_interrupt;
|
link->irq.Handler = orinoco_interrupt;
|
||||||
link->irq.Instance = priv;
|
|
||||||
|
|
||||||
/* General socket configuration defaults can go here. In this
|
/* General socket configuration defaults can go here. In this
|
||||||
* client, we assume very little, and rely on the CIS for
|
* client, we assume very little, and rely on the CIS for
|
||||||
@ -307,7 +306,7 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||||||
struct orinoco_private *priv = link->priv;
|
struct orinoco_private *priv = link->priv;
|
||||||
struct orinoco_pccard *card = priv->card;
|
struct orinoco_pccard *card = priv->card;
|
||||||
hermes_t *hw = &priv->hw;
|
hermes_t *hw = &priv->hw;
|
||||||
int last_fn, last_ret;
|
int ret;
|
||||||
void __iomem *mem;
|
void __iomem *mem;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -324,13 +323,12 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||||||
* and most client drivers will only use the CIS to fill in
|
* and most client drivers will only use the CIS to fill in
|
||||||
* implementation-defined details.
|
* implementation-defined details.
|
||||||
*/
|
*/
|
||||||
last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
|
ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret) {
|
||||||
if (!ignore_cis_vcc)
|
if (!ignore_cis_vcc)
|
||||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||||
"CIS configuration. Maybe you need the "
|
"CIS configuration. Maybe you need the "
|
||||||
"ignore_cis_vcc=1 parameter.\n");
|
"ignore_cis_vcc=1 parameter.\n");
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,14 +337,16 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||||||
* a handler to the interrupt, unless the 'Handler' member of
|
* a handler to the interrupt, unless the 'Handler' member of
|
||||||
* the irq structure is initialized.
|
* the irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* We initialize the hermes structure before completing PCMCIA
|
/* We initialize the hermes structure before completing PCMCIA
|
||||||
* configuration just in case the interrupt handler gets
|
* configuration just in case the interrupt handler gets
|
||||||
* called. */
|
* called. */
|
||||||
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
|
|
||||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||||
|
|
||||||
@ -355,8 +355,9 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||||||
* the I/O windows and the interrupt mapping, and putting the
|
* the I/O windows and the interrupt mapping, and putting the
|
||||||
* card and host interface into "Memory and IO" mode.
|
* card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
CS_CHECK(RequestConfiguration,
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* Ok, we have the configuration, prepare to register the netdev */
|
/* Ok, we have the configuration, prepare to register the netdev */
|
||||||
card->node.major = card->node.minor = 0;
|
card->node.major = card->node.minor = 0;
|
||||||
@ -386,9 +387,6 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||||||
* net_device has been registered */
|
* net_device has been registered */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
spectrum_cs_release(link);
|
spectrum_cs_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -3656,10 +3656,7 @@ wv_pcmcia_reset(struct net_device * dev)
|
|||||||
|
|
||||||
i = pcmcia_access_configuration_register(link, ®);
|
i = pcmcia_access_configuration_register(link, ®);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, AccessConfigurationRegister, i);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_CONFIG_INFO
|
#ifdef DEBUG_CONFIG_INFO
|
||||||
printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
|
printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
|
||||||
@ -3670,19 +3667,13 @@ wv_pcmcia_reset(struct net_device * dev)
|
|||||||
reg.Value = reg.Value | COR_SW_RESET;
|
reg.Value = reg.Value | COR_SW_RESET;
|
||||||
i = pcmcia_access_configuration_register(link, ®);
|
i = pcmcia_access_configuration_register(link, ®);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, AccessConfigurationRegister, i);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
|
reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
|
||||||
i = pcmcia_access_configuration_register(link, ®);
|
i = pcmcia_access_configuration_register(link, ®);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, AccessConfigurationRegister, i);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_CONFIG_TRACE
|
#ifdef DEBUG_CONFIG_TRACE
|
||||||
printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
|
printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
|
||||||
@ -3857,10 +3848,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
|
|||||||
{
|
{
|
||||||
i = pcmcia_request_io(link, &link->io);
|
i = pcmcia_request_io(link, &link->io);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, RequestIO, i);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now allocate an interrupt line. Note that this does not
|
* Now allocate an interrupt line. Note that this does not
|
||||||
@ -3868,10 +3856,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
|
|||||||
*/
|
*/
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This actually configures the PCMCIA socket -- setting up
|
* This actually configures the PCMCIA socket -- setting up
|
||||||
@ -3880,10 +3865,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
|
|||||||
link->conf.ConfigIndex = 1;
|
link->conf.ConfigIndex = 1;
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a small memory window. Note that the struct pcmcia_device
|
* Allocate a small memory window. Note that the struct pcmcia_device
|
||||||
@ -3894,24 +3876,18 @@ wv_pcmcia_config(struct pcmcia_device * link)
|
|||||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||||
req.Base = req.Size = 0;
|
req.Base = req.Size = 0;
|
||||||
req.AccessSpeed = mem_speed;
|
req.AccessSpeed = mem_speed;
|
||||||
i = pcmcia_request_window(&link, &req, &link->win);
|
i = pcmcia_request_window(link, &req, &link->win);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, RequestWindow, i);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
lp->mem = ioremap(req.Base, req.Size);
|
lp->mem = ioremap(req.Base, req.Size);
|
||||||
dev->mem_start = (u_long)lp->mem;
|
dev->mem_start = (u_long)lp->mem;
|
||||||
dev->mem_end = dev->mem_start + req.Size;
|
dev->mem_end = dev->mem_start + req.Size;
|
||||||
|
|
||||||
mem.CardOffset = 0; mem.Page = 0;
|
mem.CardOffset = 0; mem.Page = 0;
|
||||||
i = pcmcia_map_mem_page(link->win, &mem);
|
i = pcmcia_map_mem_page(link, link->win, &mem);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
|
||||||
cs_error(link, MapMemPage, i);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
/* Feed device with this info... */
|
/* Feed device with this info... */
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
@ -3923,7 +3899,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
|
|||||||
lp->mem, dev->irq, (u_int) dev->base_addr);
|
lp->mem, dev->irq, (u_int) dev->base_addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
i = register_netdev(dev);
|
i = register_netdev(dev);
|
||||||
if(i != 0)
|
if(i != 0)
|
||||||
{
|
{
|
||||||
@ -4462,8 +4438,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
|
|||||||
p_dev->io.IOAddrLines = 3;
|
p_dev->io.IOAddrLines = 3;
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
p_dev->irq.Handler = wavelan_interrupt;
|
p_dev->irq.Handler = wavelan_interrupt;
|
||||||
|
|
||||||
/* General socket configuration */
|
/* General socket configuration */
|
||||||
@ -4475,7 +4450,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
|
|||||||
if (!dev)
|
if (!dev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
p_dev->priv = p_dev->irq.Instance = dev;
|
p_dev->priv = dev;
|
||||||
|
|
||||||
lp = netdev_priv(dev);
|
lp = netdev_priv(dev);
|
||||||
|
|
||||||
|
@ -67,23 +67,7 @@
|
|||||||
/* For rough constant delay */
|
/* For rough constant delay */
|
||||||
#define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
|
#define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
|
||||||
|
|
||||||
/*
|
|
||||||
* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do not
|
|
||||||
* define PCMCIA_DEBUG at all, all the debug code will be left out. If you
|
|
||||||
* compile with PCMCIA_DEBUG=0, the debug code will be present but disabled --
|
|
||||||
* but it can then be enabled for specific modules at load time with a
|
|
||||||
* 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#define PCMCIA_DEBUG 0
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define dprintk(n, format, args...) \
|
|
||||||
{ if (pc_debug > (n)) \
|
|
||||||
printk(KERN_INFO "%s: " format "\n", __func__ , ##args); }
|
|
||||||
#else
|
|
||||||
#define dprintk(n, format, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
|
#define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
|
||||||
#define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
|
#define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
|
||||||
@ -684,10 +668,10 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
|
|||||||
int matchflag = 0;
|
int matchflag = 0;
|
||||||
struct wl3501_scan_confirm sig;
|
struct wl3501_scan_confirm sig;
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||||
if (sig.status == WL3501_STATUS_SUCCESS) {
|
if (sig.status == WL3501_STATUS_SUCCESS) {
|
||||||
dprintk(3, "success");
|
pr_debug("success");
|
||||||
if ((this->net_type == IW_MODE_INFRA &&
|
if ((this->net_type == IW_MODE_INFRA &&
|
||||||
(sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
|
(sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
|
||||||
(this->net_type == IW_MODE_ADHOC &&
|
(this->net_type == IW_MODE_ADHOC &&
|
||||||
@ -722,7 +706,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sig.status == WL3501_STATUS_TIMEOUT) {
|
} else if (sig.status == WL3501_STATUS_TIMEOUT) {
|
||||||
dprintk(3, "timeout");
|
pr_debug("timeout");
|
||||||
this->join_sta_bss = 0;
|
this->join_sta_bss = 0;
|
||||||
for (i = this->join_sta_bss; i < this->bss_cnt; i++)
|
for (i = this->join_sta_bss; i < this->bss_cnt; i++)
|
||||||
if (!wl3501_mgmt_join(this, i))
|
if (!wl3501_mgmt_join(this, i))
|
||||||
@ -879,7 +863,7 @@ static int wl3501_mgmt_auth(struct wl3501_card *this)
|
|||||||
.timeout = 1000,
|
.timeout = 1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
|
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
|
||||||
return wl3501_esbq_exec(this, &sig, sizeof(sig));
|
return wl3501_esbq_exec(this, &sig, sizeof(sig));
|
||||||
}
|
}
|
||||||
@ -893,7 +877,7 @@ static int wl3501_mgmt_association(struct wl3501_card *this)
|
|||||||
.cap_info = this->cap_info,
|
.cap_info = this->cap_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
|
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
|
||||||
return wl3501_esbq_exec(this, &sig, sizeof(sig));
|
return wl3501_esbq_exec(this, &sig, sizeof(sig));
|
||||||
}
|
}
|
||||||
@ -903,7 +887,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
|
|||||||
struct wl3501_card *this = netdev_priv(dev);
|
struct wl3501_card *this = netdev_priv(dev);
|
||||||
struct wl3501_join_confirm sig;
|
struct wl3501_join_confirm sig;
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||||
if (sig.status == WL3501_STATUS_SUCCESS) {
|
if (sig.status == WL3501_STATUS_SUCCESS) {
|
||||||
if (this->net_type == IW_MODE_INFRA) {
|
if (this->net_type == IW_MODE_INFRA) {
|
||||||
@ -962,7 +946,7 @@ static inline void wl3501_md_confirm_interrupt(struct net_device *dev,
|
|||||||
{
|
{
|
||||||
struct wl3501_md_confirm sig;
|
struct wl3501_md_confirm sig;
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||||
wl3501_free_tx_buffer(this, sig.data);
|
wl3501_free_tx_buffer(this, sig.data);
|
||||||
if (netif_queue_stopped(dev))
|
if (netif_queue_stopped(dev))
|
||||||
@ -1017,7 +1001,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
|
|||||||
static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
|
static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
|
||||||
u16 addr, void *sig, int size)
|
u16 addr, void *sig, int size)
|
||||||
{
|
{
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
|
wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
|
||||||
sizeof(this->sig_get_confirm));
|
sizeof(this->sig_get_confirm));
|
||||||
wake_up(&this->wait);
|
wake_up(&this->wait);
|
||||||
@ -1029,7 +1013,7 @@ static inline void wl3501_start_confirm_interrupt(struct net_device *dev,
|
|||||||
{
|
{
|
||||||
struct wl3501_start_confirm sig;
|
struct wl3501_start_confirm sig;
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||||
if (sig.status == WL3501_STATUS_SUCCESS)
|
if (sig.status == WL3501_STATUS_SUCCESS)
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
@ -1041,7 +1025,7 @@ static inline void wl3501_assoc_confirm_interrupt(struct net_device *dev,
|
|||||||
struct wl3501_card *this = netdev_priv(dev);
|
struct wl3501_card *this = netdev_priv(dev);
|
||||||
struct wl3501_assoc_confirm sig;
|
struct wl3501_assoc_confirm sig;
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||||
|
|
||||||
if (sig.status == WL3501_STATUS_SUCCESS)
|
if (sig.status == WL3501_STATUS_SUCCESS)
|
||||||
@ -1053,7 +1037,7 @@ static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this,
|
|||||||
{
|
{
|
||||||
struct wl3501_auth_confirm sig;
|
struct wl3501_auth_confirm sig;
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||||
|
|
||||||
if (sig.status == WL3501_STATUS_SUCCESS)
|
if (sig.status == WL3501_STATUS_SUCCESS)
|
||||||
@ -1069,7 +1053,7 @@ static inline void wl3501_rx_interrupt(struct net_device *dev)
|
|||||||
u8 sig_id;
|
u8 sig_id;
|
||||||
struct wl3501_card *this = netdev_priv(dev);
|
struct wl3501_card *this = netdev_priv(dev);
|
||||||
|
|
||||||
dprintk(3, "entry");
|
pr_debug("entry");
|
||||||
loop:
|
loop:
|
||||||
morepkts = 0;
|
morepkts = 0;
|
||||||
if (!wl3501_esbq_confirm(this))
|
if (!wl3501_esbq_confirm(this))
|
||||||
@ -1302,7 +1286,7 @@ static int wl3501_reset(struct net_device *dev)
|
|||||||
wl3501_ack_interrupt(this);
|
wl3501_ack_interrupt(this);
|
||||||
wl3501_unblock_interrupt(this);
|
wl3501_unblock_interrupt(this);
|
||||||
wl3501_mgmt_scan(this, 100);
|
wl3501_mgmt_scan(this, 100);
|
||||||
dprintk(1, "%s: device reset", dev->name);
|
pr_debug("%s: device reset", dev->name);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
@ -1376,7 +1360,7 @@ static int wl3501_open(struct net_device *dev)
|
|||||||
link->open++;
|
link->open++;
|
||||||
|
|
||||||
/* Initial WL3501 firmware */
|
/* Initial WL3501 firmware */
|
||||||
dprintk(1, "%s: Initialize WL3501 firmware...", dev->name);
|
pr_debug("%s: Initialize WL3501 firmware...", dev->name);
|
||||||
if (wl3501_init_firmware(this))
|
if (wl3501_init_firmware(this))
|
||||||
goto fail;
|
goto fail;
|
||||||
/* Initial device variables */
|
/* Initial device variables */
|
||||||
@ -1388,7 +1372,7 @@ static int wl3501_open(struct net_device *dev)
|
|||||||
wl3501_unblock_interrupt(this);
|
wl3501_unblock_interrupt(this);
|
||||||
wl3501_mgmt_scan(this, 100);
|
wl3501_mgmt_scan(this, 100);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
dprintk(1, "%s: WL3501 opened", dev->name);
|
pr_debug("%s: WL3501 opened", dev->name);
|
||||||
printk(KERN_INFO "%s: Card Name: %s\n"
|
printk(KERN_INFO "%s: Card Name: %s\n"
|
||||||
"%s: Firmware Date: %s\n",
|
"%s: Firmware Date: %s\n",
|
||||||
dev->name, this->card_name,
|
dev->name, this->card_name,
|
||||||
@ -1914,8 +1898,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
|
|||||||
p_dev->io.IOAddrLines = 5;
|
p_dev->io.IOAddrLines = 5;
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
p_dev->irq.Handler = wl3501_interrupt;
|
p_dev->irq.Handler = wl3501_interrupt;
|
||||||
|
|
||||||
/* General socket configuration */
|
/* General socket configuration */
|
||||||
@ -1938,16 +1921,13 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
|
|||||||
dev->wireless_handlers = &wl3501_handler_def;
|
dev->wireless_handlers = &wl3501_handler_def;
|
||||||
SET_ETHTOOL_OPS(dev, &ops);
|
SET_ETHTOOL_OPS(dev, &ops);
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
p_dev->priv = p_dev->irq.Instance = dev;
|
p_dev->priv = dev;
|
||||||
|
|
||||||
return wl3501_config(p_dev);
|
return wl3501_config(p_dev);
|
||||||
out_link:
|
out_link:
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wl3501_config - configure the PCMCIA socket and make eth device available
|
* wl3501_config - configure the PCMCIA socket and make eth device available
|
||||||
* @link - FILL_IN
|
* @link - FILL_IN
|
||||||
@ -1959,7 +1939,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|||||||
static int wl3501_config(struct pcmcia_device *link)
|
static int wl3501_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct net_device *dev = link->priv;
|
struct net_device *dev = link->priv;
|
||||||
int i = 0, j, last_fn, last_ret;
|
int i = 0, j, ret;
|
||||||
struct wl3501_card *this;
|
struct wl3501_card *this;
|
||||||
|
|
||||||
/* Try allocating IO ports. This tries a few fixed addresses. If you
|
/* Try allocating IO ports. This tries a few fixed addresses. If you
|
||||||
@ -1975,24 +1955,26 @@ static int wl3501_config(struct pcmcia_device *link)
|
|||||||
if (i == 0)
|
if (i == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIO, i);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
/* Now allocate an interrupt line. Note that this does not actually
|
/* Now allocate an interrupt line. Note that this does not actually
|
||||||
* assign a handler to the interrupt. */
|
* assign a handler to the interrupt. */
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* This actually configures the PCMCIA socket -- setting up the I/O
|
/* This actually configures the PCMCIA socket -- setting up the I/O
|
||||||
* windows and the interrupt mapping. */
|
* windows and the interrupt mapping. */
|
||||||
|
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
dev->irq = link->irq.AssignedIRQ;
|
dev->irq = link->irq.AssignedIRQ;
|
||||||
dev->base_addr = link->io.BasePort1;
|
dev->base_addr = link->io.BasePort1;
|
||||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
SET_NETDEV_DEV(dev, &link->dev);
|
||||||
if (register_netdev(dev)) {
|
if (register_netdev(dev)) {
|
||||||
printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
|
printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -2041,8 +2023,6 @@ static int wl3501_config(struct pcmcia_device *link)
|
|||||||
netif_start_queue(dev);
|
netif_start_queue(dev);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
wl3501_release(link);
|
wl3501_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -67,14 +67,6 @@ MODULE_LICENSE("Dual MPL/GPL");
|
|||||||
|
|
||||||
INT_MODULE_PARM(epp_mode, 1);
|
INT_MODULE_PARM(epp_mode, 1);
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"parport_cs.c 1.29 2002/10/11 06:57:41 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -103,7 +95,7 @@ static int parport_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
parport_info_t *info;
|
parport_info_t *info;
|
||||||
|
|
||||||
DEBUG(0, "parport_attach()\n");
|
dev_dbg(&link->dev, "parport_attach()\n");
|
||||||
|
|
||||||
/* Create new parport device */
|
/* Create new parport device */
|
||||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||||
@ -114,7 +106,6 @@ static int parport_probe(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -132,7 +123,7 @@ static int parport_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void parport_detach(struct pcmcia_device *link)
|
static void parport_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "parport_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "parport_detach\n");
|
||||||
|
|
||||||
parport_cs_release(link);
|
parport_cs_release(link);
|
||||||
|
|
||||||
@ -147,9 +138,6 @@ static void parport_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int parport_config_check(struct pcmcia_device *p_dev,
|
static int parport_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -178,18 +166,20 @@ static int parport_config(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
parport_info_t *info = link->priv;
|
parport_info_t *info = link->priv;
|
||||||
struct parport *p;
|
struct parport *p;
|
||||||
int last_ret, last_fn;
|
int ret;
|
||||||
|
|
||||||
DEBUG(0, "parport_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "parport_config\n");
|
||||||
|
|
||||||
last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
|
ret = pcmcia_loop_config(link, parport_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
|
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
|
||||||
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
|
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
|
||||||
@ -213,8 +203,6 @@ static int parport_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
parport_cs_release(link);
|
parport_cs_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -232,7 +220,7 @@ static void parport_cs_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
parport_info_t *info = link->priv;
|
parport_info_t *info = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "parport_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "parport_release\n");
|
||||||
|
|
||||||
if (info->ndev) {
|
if (info->ndev) {
|
||||||
struct parport *p = info->port;
|
struct parport *p = info->port;
|
||||||
|
@ -17,24 +17,6 @@ menuconfig PCCARD
|
|||||||
|
|
||||||
if PCCARD
|
if PCCARD
|
||||||
|
|
||||||
config PCMCIA_DEBUG
|
|
||||||
bool "Enable PCCARD debugging"
|
|
||||||
help
|
|
||||||
Say Y here to enable PCMCIA subsystem debugging. You
|
|
||||||
will need to choose the debugging level either via the
|
|
||||||
kernel command line, or module options depending whether
|
|
||||||
you build the PCMCIA as modules.
|
|
||||||
|
|
||||||
The kernel command line options are:
|
|
||||||
pcmcia_core.pc_debug=N
|
|
||||||
pcmcia.pc_debug=N
|
|
||||||
sa11xx_core.pc_debug=N
|
|
||||||
|
|
||||||
The module option is called pc_debug=N
|
|
||||||
|
|
||||||
In all the above examples, N is the debugging verbosity
|
|
||||||
level.
|
|
||||||
|
|
||||||
config PCMCIA
|
config PCMCIA
|
||||||
tristate "16-bit PCMCIA support"
|
tristate "16-bit PCMCIA support"
|
||||||
select CRC32
|
select CRC32
|
||||||
@ -196,9 +178,13 @@ config PCMCIA_BCM63XX
|
|||||||
tristate "bcm63xx pcmcia support"
|
tristate "bcm63xx pcmcia support"
|
||||||
depends on BCM63XX && PCMCIA
|
depends on BCM63XX && PCMCIA
|
||||||
|
|
||||||
|
config PCMCIA_SOC_COMMON
|
||||||
|
bool
|
||||||
|
|
||||||
config PCMCIA_SA1100
|
config PCMCIA_SA1100
|
||||||
tristate "SA1100 support"
|
tristate "SA1100 support"
|
||||||
depends on ARM && ARCH_SA1100 && PCMCIA
|
depends on ARM && ARCH_SA1100 && PCMCIA
|
||||||
|
select PCMCIA_SOC_COMMON
|
||||||
help
|
help
|
||||||
Say Y here to include support for SA11x0-based PCMCIA or CF
|
Say Y here to include support for SA11x0-based PCMCIA or CF
|
||||||
sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
|
sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
|
||||||
@ -209,6 +195,7 @@ config PCMCIA_SA1100
|
|||||||
config PCMCIA_SA1111
|
config PCMCIA_SA1111
|
||||||
tristate "SA1111 support"
|
tristate "SA1111 support"
|
||||||
depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
|
depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
|
||||||
|
select PCMCIA_SOC_COMMON
|
||||||
help
|
help
|
||||||
Say Y here to include support for SA1111-based PCMCIA or CF
|
Say Y here to include support for SA1111-based PCMCIA or CF
|
||||||
sockets, found on the Jornada 720, Graphicsmaster and other
|
sockets, found on the Jornada 720, Graphicsmaster and other
|
||||||
@ -222,9 +209,28 @@ config PCMCIA_PXA2XX
|
|||||||
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|
||||||
|| MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|
|| MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|
||||||
|| ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2)
|
|| ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2)
|
||||||
|
select PCMCIA_SOC_COMMON
|
||||||
help
|
help
|
||||||
Say Y here to include support for the PXA2xx PCMCIA controller
|
Say Y here to include support for the PXA2xx PCMCIA controller
|
||||||
|
|
||||||
|
config PCMCIA_DEBUG
|
||||||
|
bool "Enable debugging"
|
||||||
|
depends on (PCMCIA_SA1111 || PCMCIA_SA1100 || PCMCIA_PXA2XX)
|
||||||
|
help
|
||||||
|
Say Y here to enable debugging for the SoC PCMCIA layer.
|
||||||
|
You will need to choose the debugging level either via the
|
||||||
|
kernel command line, or module options depending whether
|
||||||
|
you build the drivers as modules.
|
||||||
|
|
||||||
|
The kernel command line options are:
|
||||||
|
sa11xx_core.pc_debug=N
|
||||||
|
pxa2xx_core.pc_debug=N
|
||||||
|
|
||||||
|
The module option is called pc_debug=N
|
||||||
|
|
||||||
|
In all the above examples, N is the debugging verbosity
|
||||||
|
level.
|
||||||
|
|
||||||
config PCMCIA_PROBE
|
config PCMCIA_PROBE
|
||||||
bool
|
bool
|
||||||
default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
|
default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
|
||||||
|
@ -22,8 +22,9 @@ obj-$(CONFIG_I82365) += i82365.o
|
|||||||
obj-$(CONFIG_I82092) += i82092.o
|
obj-$(CONFIG_I82092) += i82092.o
|
||||||
obj-$(CONFIG_TCIC) += tcic.o
|
obj-$(CONFIG_TCIC) += tcic.o
|
||||||
obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
|
obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
|
||||||
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
|
obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o
|
||||||
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
|
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o
|
||||||
|
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o
|
||||||
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
|
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
|
||||||
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
|
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
|
||||||
obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
|
obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
|
||||||
@ -35,9 +36,6 @@ obj-$(CONFIG_BFIN_CFPCMCIA) += bfin_cf_pcmcia.o
|
|||||||
obj-$(CONFIG_AT91_CF) += at91_cf.o
|
obj-$(CONFIG_AT91_CF) += at91_cf.o
|
||||||
obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
|
obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
|
||||||
|
|
||||||
sa11xx_core-y += soc_common.o sa11xx_base.o
|
|
||||||
pxa2xx_core-y += soc_common.o pxa2xx_base.o
|
|
||||||
|
|
||||||
au1x00_ss-y += au1000_generic.o
|
au1x00_ss-y += au1000_generic.o
|
||||||
au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
|
au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
|
||||||
au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o
|
au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o
|
||||||
@ -77,4 +75,4 @@ pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
|
|||||||
pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
|
pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
|
||||||
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
|
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
|
||||||
|
|
||||||
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
|
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y)
|
||||||
|
@ -91,7 +91,7 @@ static u_int xlate_rom_addr(void __iomem *b, u_int addr)
|
|||||||
static void cb_release_cis_mem(struct pcmcia_socket * s)
|
static void cb_release_cis_mem(struct pcmcia_socket * s)
|
||||||
{
|
{
|
||||||
if (s->cb_cis_virt) {
|
if (s->cb_cis_virt) {
|
||||||
cs_dbg(s, 1, "cb_release_cis_mem()\n");
|
dev_dbg(&s->dev, "cb_release_cis_mem()\n");
|
||||||
iounmap(s->cb_cis_virt);
|
iounmap(s->cb_cis_virt);
|
||||||
s->cb_cis_virt = NULL;
|
s->cb_cis_virt = NULL;
|
||||||
s->cb_cis_res = NULL;
|
s->cb_cis_res = NULL;
|
||||||
@ -132,7 +132,7 @@ int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void
|
|||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
|
dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
|
||||||
|
|
||||||
dev = pci_get_slot(s->cb_dev->subordinate, 0);
|
dev = pci_get_slot(s->cb_dev->subordinate, 0);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
|
@ -30,16 +30,6 @@
|
|||||||
#ifndef _LINUX_CIRRUS_H
|
#ifndef _LINUX_CIRRUS_H
|
||||||
#define _LINUX_CIRRUS_H
|
#define _LINUX_CIRRUS_H
|
||||||
|
|
||||||
#ifndef PCI_VENDOR_ID_CIRRUS
|
|
||||||
#define PCI_VENDOR_ID_CIRRUS 0x1013
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_CIRRUS_6729
|
|
||||||
#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_CIRRUS_6832
|
|
||||||
#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PD67_MISC_CTL_1 0x16 /* Misc control 1 */
|
#define PD67_MISC_CTL_1 0x16 /* Misc control 1 */
|
||||||
#define PD67_FIFO_CTL 0x17 /* FIFO control */
|
#define PD67_FIFO_CTL 0x17 /* FIFO control */
|
||||||
#define PD67_MISC_CTL_2 0x1E /* Misc control 2 */
|
#define PD67_MISC_CTL_2 0x1E /* Misc control 2 */
|
||||||
|
@ -138,7 +138,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||||||
void __iomem *sys, *end;
|
void __iomem *sys, *end;
|
||||||
unsigned char *buf = ptr;
|
unsigned char *buf = ptr;
|
||||||
|
|
||||||
cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||||
|
|
||||||
if (attr & IS_INDIRECT) {
|
if (attr & IS_INDIRECT) {
|
||||||
/* Indirect accesses use a bunch of special registers at fixed
|
/* Indirect accesses use a bunch of special registers at fixed
|
||||||
@ -190,7 +190,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||||||
addr = 0;
|
addr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cs_dbg(s, 3, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
|
dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
|
||||||
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
|
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
|
||||||
*(u_char *)(ptr+2), *(u_char *)(ptr+3));
|
*(u_char *)(ptr+2), *(u_char *)(ptr+3));
|
||||||
return 0;
|
return 0;
|
||||||
@ -204,7 +204,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||||||
void __iomem *sys, *end;
|
void __iomem *sys, *end;
|
||||||
unsigned char *buf = ptr;
|
unsigned char *buf = ptr;
|
||||||
|
|
||||||
cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||||
|
|
||||||
if (attr & IS_INDIRECT) {
|
if (attr & IS_INDIRECT) {
|
||||||
/* Indirect accesses use a bunch of special registers at fixed
|
/* Indirect accesses use a bunch of special registers at fixed
|
||||||
@ -584,7 +584,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
|
|||||||
ofs += link[1] + 2;
|
ofs += link[1] + 2;
|
||||||
}
|
}
|
||||||
if (i == MAX_TUPLES) {
|
if (i == MAX_TUPLES) {
|
||||||
cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
|
dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,7 +1440,7 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
__cs_dbg(0, "parse_tuple failed %d\n", ret);
|
pr_debug("parse_tuple failed %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pcmcia_parse_tuple);
|
EXPORT_SYMBOL(pcmcia_parse_tuple);
|
||||||
@ -1482,6 +1482,67 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pccard_read_tuple);
|
EXPORT_SYMBOL(pccard_read_tuple);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pccard_loop_tuple() - loop over tuples in the CIS
|
||||||
|
* @s: the struct pcmcia_socket where the card is inserted
|
||||||
|
* @function: the device function we loop for
|
||||||
|
* @code: which CIS code shall we look for?
|
||||||
|
* @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
|
||||||
|
* @priv_data: private data to be passed to the loop_tuple function.
|
||||||
|
* @loop_tuple: function to call for each CIS entry of type @function. IT
|
||||||
|
* gets passed the raw tuple, the paresed tuple (if @parse is
|
||||||
|
* set) and @priv_data.
|
||||||
|
*
|
||||||
|
* pccard_loop_tuple() loops over all CIS entries of type @function, and
|
||||||
|
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
|
||||||
|
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
|
||||||
|
*/
|
||||||
|
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||||
|
cisdata_t code, cisparse_t *parse, void *priv_data,
|
||||||
|
int (*loop_tuple) (tuple_t *tuple,
|
||||||
|
cisparse_t *parse,
|
||||||
|
void *priv_data))
|
||||||
|
{
|
||||||
|
tuple_t tuple;
|
||||||
|
cisdata_t *buf;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
buf = kzalloc(256, GFP_KERNEL);
|
||||||
|
if (buf == NULL) {
|
||||||
|
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
tuple.TupleData = buf;
|
||||||
|
tuple.TupleDataMax = 255;
|
||||||
|
tuple.TupleOffset = 0;
|
||||||
|
tuple.DesiredTuple = code;
|
||||||
|
tuple.Attributes = 0;
|
||||||
|
|
||||||
|
ret = pccard_get_first_tuple(s, function, &tuple);
|
||||||
|
while (!ret) {
|
||||||
|
if (pccard_get_tuple_data(s, &tuple))
|
||||||
|
goto next_entry;
|
||||||
|
|
||||||
|
if (parse)
|
||||||
|
if (pcmcia_parse_tuple(&tuple, parse))
|
||||||
|
goto next_entry;
|
||||||
|
|
||||||
|
ret = loop_tuple(&tuple, parse, priv_data);
|
||||||
|
if (!ret)
|
||||||
|
break;
|
||||||
|
|
||||||
|
next_entry:
|
||||||
|
ret = pccard_get_next_tuple(s, function, &tuple);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(pccard_loop_tuple);
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
|
|
||||||
This tries to determine if a card has a sensible CIS. It returns
|
This tries to determine if a card has a sensible CIS. It returns
|
||||||
|
@ -61,17 +61,6 @@ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
|
|||||||
/* Access speed for attribute memory windows */
|
/* Access speed for attribute memory windows */
|
||||||
INT_MODULE_PARM(cis_speed, 300); /* ns */
|
INT_MODULE_PARM(cis_speed, 300); /* ns */
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
static int pc_debug;
|
|
||||||
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
|
|
||||||
int cs_debug_level(int level)
|
|
||||||
{
|
|
||||||
return pc_debug > level;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
socket_state_t dead_socket = {
|
socket_state_t dead_socket = {
|
||||||
.csc_mask = SS_DETECT,
|
.csc_mask = SS_DETECT,
|
||||||
@ -190,7 +179,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
|
|||||||
if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
|
if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
|
dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops);
|
||||||
|
|
||||||
spin_lock_init(&socket->lock);
|
spin_lock_init(&socket->lock);
|
||||||
|
|
||||||
@ -262,6 +251,13 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
|
|||||||
|
|
||||||
pcmcia_parse_events(socket, SS_DETECT);
|
pcmcia_parse_events(socket, SS_DETECT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let's try to get the PCMCIA module for 16-bit PCMCIA support.
|
||||||
|
* If it fails, it doesn't matter -- we still have 32-bit CardBus
|
||||||
|
* support to offer, so this is not a failure mode.
|
||||||
|
*/
|
||||||
|
request_module_nowait("pcmcia");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -282,7 +278,7 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket)
|
|||||||
if (!socket)
|
if (!socket)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
|
dev_dbg(&socket->dev, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
|
||||||
|
|
||||||
if (socket->thread)
|
if (socket->thread)
|
||||||
kthread_stop(socket->thread);
|
kthread_stop(socket->thread);
|
||||||
@ -335,7 +331,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
|
|||||||
if (s->state & SOCKET_CARDBUS)
|
if (s->state & SOCKET_CARDBUS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
|
dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
|
||||||
event, priority, s->callback);
|
event, priority, s->callback);
|
||||||
|
|
||||||
if (!s->callback)
|
if (!s->callback)
|
||||||
@ -352,7 +348,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
|
|||||||
|
|
||||||
static void socket_remove_drivers(struct pcmcia_socket *skt)
|
static void socket_remove_drivers(struct pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
cs_dbg(skt, 4, "remove_drivers\n");
|
dev_dbg(&skt->dev, "remove_drivers\n");
|
||||||
|
|
||||||
send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
|
send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
|
||||||
}
|
}
|
||||||
@ -361,7 +357,7 @@ static int socket_reset(struct pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
int status, i;
|
int status, i;
|
||||||
|
|
||||||
cs_dbg(skt, 4, "reset\n");
|
dev_dbg(&skt->dev, "reset\n");
|
||||||
|
|
||||||
skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
|
skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
|
||||||
skt->ops->set_socket(skt, &skt->socket);
|
skt->ops->set_socket(skt, &skt->socket);
|
||||||
@ -383,7 +379,7 @@ static int socket_reset(struct pcmcia_socket *skt)
|
|||||||
msleep(unreset_check * 10);
|
msleep(unreset_check * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
cs_err(skt, "time out after reset.\n");
|
dev_printk(KERN_ERR, &skt->dev, "time out after reset.\n");
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +393,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
cs_dbg(s, 4, "shutdown\n");
|
dev_dbg(&s->dev, "shutdown\n");
|
||||||
|
|
||||||
socket_remove_drivers(s);
|
socket_remove_drivers(s);
|
||||||
s->state &= SOCKET_INUSE | SOCKET_PRESENT;
|
s->state &= SOCKET_INUSE | SOCKET_PRESENT;
|
||||||
@ -432,7 +428,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
|
|||||||
{
|
{
|
||||||
int status, i;
|
int status, i;
|
||||||
|
|
||||||
cs_dbg(skt, 4, "setup\n");
|
dev_dbg(&skt->dev, "setup\n");
|
||||||
|
|
||||||
skt->ops->get_status(skt, &status);
|
skt->ops->get_status(skt, &status);
|
||||||
if (!(status & SS_DETECT))
|
if (!(status & SS_DETECT))
|
||||||
@ -452,13 +448,15 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status & SS_PENDING) {
|
if (status & SS_PENDING) {
|
||||||
cs_err(skt, "voltage interrogation timed out.\n");
|
dev_printk(KERN_ERR, &skt->dev,
|
||||||
|
"voltage interrogation timed out.\n");
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & SS_CARDBUS) {
|
if (status & SS_CARDBUS) {
|
||||||
if (!(skt->features & SS_CAP_CARDBUS)) {
|
if (!(skt->features & SS_CAP_CARDBUS)) {
|
||||||
cs_err(skt, "cardbus cards are not supported.\n");
|
dev_printk(KERN_ERR, &skt->dev,
|
||||||
|
"cardbus cards are not supported.\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
skt->state |= SOCKET_CARDBUS;
|
skt->state |= SOCKET_CARDBUS;
|
||||||
@ -472,7 +470,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
|
|||||||
else if (!(status & SS_XVCARD))
|
else if (!(status & SS_XVCARD))
|
||||||
skt->socket.Vcc = skt->socket.Vpp = 50;
|
skt->socket.Vcc = skt->socket.Vpp = 50;
|
||||||
else {
|
else {
|
||||||
cs_err(skt, "unsupported voltage key.\n");
|
dev_printk(KERN_ERR, &skt->dev, "unsupported voltage key.\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,7 +487,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
|
|||||||
|
|
||||||
skt->ops->get_status(skt, &status);
|
skt->ops->get_status(skt, &status);
|
||||||
if (!(status & SS_POWERON)) {
|
if (!(status & SS_POWERON)) {
|
||||||
cs_err(skt, "unable to apply power.\n");
|
dev_printk(KERN_ERR, &skt->dev, "unable to apply power.\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,7 +507,7 @@ static int socket_insert(struct pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cs_dbg(skt, 4, "insert\n");
|
dev_dbg(&skt->dev, "insert\n");
|
||||||
|
|
||||||
if (!cs_socket_get(skt))
|
if (!cs_socket_get(skt))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -529,7 +527,7 @@ static int socket_insert(struct pcmcia_socket *skt)
|
|||||||
skt->state |= SOCKET_CARDBUS_CONFIG;
|
skt->state |= SOCKET_CARDBUS_CONFIG;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
cs_dbg(skt, 4, "insert done\n");
|
dev_dbg(&skt->dev, "insert done\n");
|
||||||
|
|
||||||
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
|
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
|
||||||
} else {
|
} else {
|
||||||
@ -576,7 +574,7 @@ static int socket_late_resume(struct pcmcia_socket *skt)
|
|||||||
* FIXME: need a better check here for cardbus cards.
|
* FIXME: need a better check here for cardbus cards.
|
||||||
*/
|
*/
|
||||||
if (verify_cis_cache(skt) != 0) {
|
if (verify_cis_cache(skt) != 0) {
|
||||||
cs_dbg(skt, 4, "cis mismatch - different card\n");
|
dev_dbg(&skt->dev, "cis mismatch - different card\n");
|
||||||
socket_remove_drivers(skt);
|
socket_remove_drivers(skt);
|
||||||
destroy_cis_cache(skt);
|
destroy_cis_cache(skt);
|
||||||
/*
|
/*
|
||||||
@ -587,7 +585,7 @@ static int socket_late_resume(struct pcmcia_socket *skt)
|
|||||||
msleep(200);
|
msleep(200);
|
||||||
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
|
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
|
||||||
} else {
|
} else {
|
||||||
cs_dbg(skt, 4, "cis matches cache\n");
|
dev_dbg(&skt->dev, "cis matches cache\n");
|
||||||
send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
|
send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -723,7 +721,7 @@ static int pccardd(void *__skt)
|
|||||||
void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
|
void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
cs_dbg(s, 4, "parse_events: events %08x\n", events);
|
dev_dbg(&s->dev, "parse_events: events %08x\n", events);
|
||||||
if (s->thread) {
|
if (s->thread) {
|
||||||
spin_lock_irqsave(&s->thread_lock, flags);
|
spin_lock_irqsave(&s->thread_lock, flags);
|
||||||
s->thread_events |= events;
|
s->thread_events |= events;
|
||||||
@ -773,19 +771,22 @@ int pcmcia_reset_card(struct pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cs_dbg(skt, 1, "resetting socket\n");
|
dev_dbg(&skt->dev, "resetting socket\n");
|
||||||
|
|
||||||
mutex_lock(&skt->skt_mutex);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
if (!(skt->state & SOCKET_PRESENT)) {
|
if (!(skt->state & SOCKET_PRESENT)) {
|
||||||
|
dev_dbg(&skt->dev, "can't reset, not present\n");
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (skt->state & SOCKET_SUSPEND) {
|
if (skt->state & SOCKET_SUSPEND) {
|
||||||
|
dev_dbg(&skt->dev, "can't reset, suspended\n");
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (skt->state & SOCKET_CARDBUS) {
|
if (skt->state & SOCKET_CARDBUS) {
|
||||||
|
dev_dbg(&skt->dev, "can't reset, is cardbus\n");
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -818,7 +819,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cs_dbg(skt, 1, "suspending socket\n");
|
dev_dbg(&skt->dev, "suspending socket\n");
|
||||||
|
|
||||||
mutex_lock(&skt->skt_mutex);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
@ -848,7 +849,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cs_dbg(skt, 1, "waking up socket\n");
|
dev_dbg(&skt->dev, "waking up socket\n");
|
||||||
|
|
||||||
mutex_lock(&skt->skt_mutex);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
@ -876,7 +877,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cs_dbg(skt, 1, "user eject request\n");
|
dev_dbg(&skt->dev, "user eject request\n");
|
||||||
|
|
||||||
mutex_lock(&skt->skt_mutex);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
@ -905,7 +906,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cs_dbg(skt, 1, "user insert request\n");
|
dev_dbg(&skt->dev, "user insert request\n");
|
||||||
|
|
||||||
mutex_lock(&skt->skt_mutex);
|
mutex_lock(&skt->skt_mutex);
|
||||||
do {
|
do {
|
||||||
|
@ -107,28 +107,6 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
extern int cs_debug_level(int);
|
|
||||||
|
|
||||||
#define cs_dbg(skt, lvl, fmt, arg...) do { \
|
|
||||||
if (cs_debug_level(lvl)) \
|
|
||||||
dev_printk(KERN_DEBUG, &skt->dev, \
|
|
||||||
"cs: " fmt, ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#define __cs_dbg(lvl, fmt, arg...) do { \
|
|
||||||
if (cs_debug_level(lvl)) \
|
|
||||||
printk(KERN_DEBUG \
|
|
||||||
"cs: " fmt, ## arg); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
|
|
||||||
#define __cs_dbg(lvl, fmt, arg...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define cs_err(skt, fmt, arg...) \
|
|
||||||
dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stuff internal to module "pcmcia_core":
|
* Stuff internal to module "pcmcia_core":
|
||||||
@ -170,10 +148,6 @@ extern struct rw_semaphore pcmcia_socket_list_rwsem;
|
|||||||
extern struct list_head pcmcia_socket_list;
|
extern struct list_head pcmcia_socket_list;
|
||||||
extern struct class pcmcia_socket_class;
|
extern struct class pcmcia_socket_class;
|
||||||
|
|
||||||
int pcmcia_get_window(struct pcmcia_socket *s,
|
|
||||||
window_handle_t *handle,
|
|
||||||
int idx,
|
|
||||||
win_req_t *req);
|
|
||||||
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
||||||
struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
|
struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
|
||||||
|
|
||||||
@ -199,6 +173,22 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
|
|||||||
const u8 *data, const size_t len);
|
const u8 *data, const size_t len);
|
||||||
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
|
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
|
||||||
|
|
||||||
|
/* loop over CIS entries */
|
||||||
|
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||||
|
cisdata_t code, cisparse_t *parse, void *priv_data,
|
||||||
|
int (*loop_tuple) (tuple_t *tuple,
|
||||||
|
cisparse_t *parse,
|
||||||
|
void *priv_data));
|
||||||
|
|
||||||
|
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||||
|
tuple_t *tuple);
|
||||||
|
|
||||||
|
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||||
|
tuple_t *tuple);
|
||||||
|
|
||||||
|
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
|
||||||
|
|
||||||
|
|
||||||
/* rsrc_mgr.c */
|
/* rsrc_mgr.c */
|
||||||
int pcmcia_validate_mem(struct pcmcia_socket *s);
|
int pcmcia_validate_mem(struct pcmcia_socket *s);
|
||||||
struct resource *pcmcia_find_io_region(unsigned long base,
|
struct resource *pcmcia_find_io_region(unsigned long base,
|
||||||
|
@ -41,129 +41,11 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
|||||||
MODULE_DESCRIPTION("PCMCIA Driver Services");
|
MODULE_DESCRIPTION("PCMCIA Driver Services");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
int ds_pc_debug;
|
|
||||||
|
|
||||||
module_param_named(pc_debug, ds_pc_debug, int, 0644);
|
|
||||||
|
|
||||||
#define ds_dbg(lvl, fmt, arg...) do { \
|
|
||||||
if (ds_pc_debug > (lvl)) \
|
|
||||||
printk(KERN_DEBUG "ds: " fmt , ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#define ds_dev_dbg(lvl, dev, fmt, arg...) do { \
|
|
||||||
if (ds_pc_debug > (lvl)) \
|
|
||||||
dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
|
|
||||||
#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
spinlock_t pcmcia_dev_list_lock;
|
spinlock_t pcmcia_dev_list_lock;
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
/* code which was in cs.c before */
|
|
||||||
|
|
||||||
/* String tables for error messages */
|
|
||||||
|
|
||||||
typedef struct lookup_t {
|
|
||||||
const int key;
|
|
||||||
const char *msg;
|
|
||||||
} lookup_t;
|
|
||||||
|
|
||||||
static const lookup_t error_table[] = {
|
|
||||||
{ 0, "Operation succeeded" },
|
|
||||||
{ -EIO, "Input/Output error" },
|
|
||||||
{ -ENODEV, "No card present" },
|
|
||||||
{ -EINVAL, "Bad parameter" },
|
|
||||||
{ -EACCES, "Configuration locked" },
|
|
||||||
{ -EBUSY, "Resource in use" },
|
|
||||||
{ -ENOSPC, "No more items" },
|
|
||||||
{ -ENOMEM, "Out of resource" },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const lookup_t service_table[] = {
|
|
||||||
{ AccessConfigurationRegister, "AccessConfigurationRegister" },
|
|
||||||
{ AddSocketServices, "AddSocketServices" },
|
|
||||||
{ AdjustResourceInfo, "AdjustResourceInfo" },
|
|
||||||
{ CheckEraseQueue, "CheckEraseQueue" },
|
|
||||||
{ CloseMemory, "CloseMemory" },
|
|
||||||
{ DeregisterClient, "DeregisterClient" },
|
|
||||||
{ DeregisterEraseQueue, "DeregisterEraseQueue" },
|
|
||||||
{ GetCardServicesInfo, "GetCardServicesInfo" },
|
|
||||||
{ GetClientInfo, "GetClientInfo" },
|
|
||||||
{ GetConfigurationInfo, "GetConfigurationInfo" },
|
|
||||||
{ GetEventMask, "GetEventMask" },
|
|
||||||
{ GetFirstClient, "GetFirstClient" },
|
|
||||||
{ GetFirstRegion, "GetFirstRegion" },
|
|
||||||
{ GetFirstTuple, "GetFirstTuple" },
|
|
||||||
{ GetNextClient, "GetNextClient" },
|
|
||||||
{ GetNextRegion, "GetNextRegion" },
|
|
||||||
{ GetNextTuple, "GetNextTuple" },
|
|
||||||
{ GetStatus, "GetStatus" },
|
|
||||||
{ GetTupleData, "GetTupleData" },
|
|
||||||
{ MapMemPage, "MapMemPage" },
|
|
||||||
{ ModifyConfiguration, "ModifyConfiguration" },
|
|
||||||
{ ModifyWindow, "ModifyWindow" },
|
|
||||||
{ OpenMemory, "OpenMemory" },
|
|
||||||
{ ParseTuple, "ParseTuple" },
|
|
||||||
{ ReadMemory, "ReadMemory" },
|
|
||||||
{ RegisterClient, "RegisterClient" },
|
|
||||||
{ RegisterEraseQueue, "RegisterEraseQueue" },
|
|
||||||
{ RegisterMTD, "RegisterMTD" },
|
|
||||||
{ ReleaseConfiguration, "ReleaseConfiguration" },
|
|
||||||
{ ReleaseIO, "ReleaseIO" },
|
|
||||||
{ ReleaseIRQ, "ReleaseIRQ" },
|
|
||||||
{ ReleaseWindow, "ReleaseWindow" },
|
|
||||||
{ RequestConfiguration, "RequestConfiguration" },
|
|
||||||
{ RequestIO, "RequestIO" },
|
|
||||||
{ RequestIRQ, "RequestIRQ" },
|
|
||||||
{ RequestSocketMask, "RequestSocketMask" },
|
|
||||||
{ RequestWindow, "RequestWindow" },
|
|
||||||
{ ResetCard, "ResetCard" },
|
|
||||||
{ SetEventMask, "SetEventMask" },
|
|
||||||
{ ValidateCIS, "ValidateCIS" },
|
|
||||||
{ WriteMemory, "WriteMemory" },
|
|
||||||
{ BindDevice, "BindDevice" },
|
|
||||||
{ BindMTD, "BindMTD" },
|
|
||||||
{ ReportError, "ReportError" },
|
|
||||||
{ SuspendCard, "SuspendCard" },
|
|
||||||
{ ResumeCard, "ResumeCard" },
|
|
||||||
{ EjectCard, "EjectCard" },
|
|
||||||
{ InsertCard, "InsertCard" },
|
|
||||||
{ ReplaceCIS, "ReplaceCIS" }
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *pcmcia_error_func(int func)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(service_table); i++)
|
|
||||||
if (service_table[i].key == func)
|
|
||||||
return service_table[i].msg;
|
|
||||||
|
|
||||||
return "Unknown service number";
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(pcmcia_error_func);
|
|
||||||
|
|
||||||
const char *pcmcia_error_ret(int ret)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(error_table); i++)
|
|
||||||
if (error_table[i].key == ret)
|
|
||||||
return error_table[i].msg;
|
|
||||||
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(pcmcia_error_ret);
|
|
||||||
|
|
||||||
/*======================================================================*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
|
static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
|
||||||
{
|
{
|
||||||
struct pcmcia_device_id *did = p_drv->id_table;
|
struct pcmcia_device_id *did = p_drv->id_table;
|
||||||
@ -303,7 +185,7 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
|
|||||||
spin_lock_init(&driver->dynids.lock);
|
spin_lock_init(&driver->dynids.lock);
|
||||||
INIT_LIST_HEAD(&driver->dynids.list);
|
INIT_LIST_HEAD(&driver->dynids.list);
|
||||||
|
|
||||||
ds_dbg(3, "registering driver %s\n", driver->drv.name);
|
pr_debug("registering driver %s\n", driver->drv.name);
|
||||||
|
|
||||||
error = driver_register(&driver->drv);
|
error = driver_register(&driver->drv);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
@ -323,7 +205,7 @@ EXPORT_SYMBOL(pcmcia_register_driver);
|
|||||||
*/
|
*/
|
||||||
void pcmcia_unregister_driver(struct pcmcia_driver *driver)
|
void pcmcia_unregister_driver(struct pcmcia_driver *driver)
|
||||||
{
|
{
|
||||||
ds_dbg(3, "unregistering driver %s\n", driver->drv.name);
|
pr_debug("unregistering driver %s\n", driver->drv.name);
|
||||||
driver_unregister(&driver->drv);
|
driver_unregister(&driver->drv);
|
||||||
pcmcia_free_dynids(driver);
|
pcmcia_free_dynids(driver);
|
||||||
}
|
}
|
||||||
@ -350,14 +232,14 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev)
|
|||||||
static void pcmcia_release_function(struct kref *ref)
|
static void pcmcia_release_function(struct kref *ref)
|
||||||
{
|
{
|
||||||
struct config_t *c = container_of(ref, struct config_t, ref);
|
struct config_t *c = container_of(ref, struct config_t, ref);
|
||||||
ds_dbg(1, "releasing config_t\n");
|
pr_debug("releasing config_t\n");
|
||||||
kfree(c);
|
kfree(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcmcia_release_dev(struct device *dev)
|
static void pcmcia_release_dev(struct device *dev)
|
||||||
{
|
{
|
||||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
ds_dev_dbg(1, dev, "releasing device\n");
|
dev_dbg(dev, "releasing device\n");
|
||||||
pcmcia_put_socket(p_dev->socket);
|
pcmcia_put_socket(p_dev->socket);
|
||||||
kfree(p_dev->devname);
|
kfree(p_dev->devname);
|
||||||
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
|
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
|
||||||
@ -367,7 +249,7 @@ static void pcmcia_release_dev(struct device *dev)
|
|||||||
static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
|
static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
|
||||||
{
|
{
|
||||||
if (!s->pcmcia_state.device_add_pending) {
|
if (!s->pcmcia_state.device_add_pending) {
|
||||||
ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary"
|
dev_dbg(&s->dev, "scheduling to add %s secondary"
|
||||||
" device to %d\n", mfc ? "mfc" : "pfc", s->sock);
|
" device to %d\n", mfc ? "mfc" : "pfc", s->sock);
|
||||||
s->pcmcia_state.device_add_pending = 1;
|
s->pcmcia_state.device_add_pending = 1;
|
||||||
s->pcmcia_state.mfc_pfc = mfc;
|
s->pcmcia_state.mfc_pfc = mfc;
|
||||||
@ -405,7 +287,7 @@ static int pcmcia_device_probe(struct device * dev)
|
|||||||
*/
|
*/
|
||||||
did = dev_get_drvdata(&p_dev->dev);
|
did = dev_get_drvdata(&p_dev->dev);
|
||||||
|
|
||||||
ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
|
dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name);
|
||||||
|
|
||||||
if ((!p_drv->probe) || (!p_dev->function_config) ||
|
if ((!p_drv->probe) || (!p_dev->function_config) ||
|
||||||
(!try_module_get(p_drv->owner))) {
|
(!try_module_get(p_drv->owner))) {
|
||||||
@ -428,7 +310,7 @@ static int pcmcia_device_probe(struct device * dev)
|
|||||||
|
|
||||||
ret = p_drv->probe(p_dev);
|
ret = p_drv->probe(p_dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ds_dev_dbg(1, dev, "binding to %s failed with %d\n",
|
dev_dbg(dev, "binding to %s failed with %d\n",
|
||||||
p_drv->drv.name, ret);
|
p_drv->drv.name, ret);
|
||||||
goto put_module;
|
goto put_module;
|
||||||
}
|
}
|
||||||
@ -456,7 +338,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
|
|||||||
struct pcmcia_device *tmp;
|
struct pcmcia_device *tmp;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
|
dev_dbg(leftover ? &leftover->dev : &s->dev,
|
||||||
"pcmcia_card_remove(%d) %s\n", s->sock,
|
"pcmcia_card_remove(%d) %s\n", s->sock,
|
||||||
leftover ? leftover->devname : "");
|
leftover ? leftover->devname : "");
|
||||||
|
|
||||||
@ -475,7 +357,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
|
|||||||
p_dev->_removed=1;
|
p_dev->_removed=1;
|
||||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||||
|
|
||||||
ds_dev_dbg(2, &p_dev->dev, "unregistering device\n");
|
dev_dbg(&p_dev->dev, "unregistering device\n");
|
||||||
device_unregister(&p_dev->dev);
|
device_unregister(&p_dev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,7 +374,7 @@ static int pcmcia_device_remove(struct device * dev)
|
|||||||
p_dev = to_pcmcia_dev(dev);
|
p_dev = to_pcmcia_dev(dev);
|
||||||
p_drv = to_pcmcia_drv(dev->driver);
|
p_drv = to_pcmcia_drv(dev->driver);
|
||||||
|
|
||||||
ds_dev_dbg(1, dev, "removing device\n");
|
dev_dbg(dev, "removing device\n");
|
||||||
|
|
||||||
/* If we're removing the primary module driving a
|
/* If we're removing the primary module driving a
|
||||||
* pseudo multi-function card, we need to unbind
|
* pseudo multi-function card, we need to unbind
|
||||||
@ -572,7 +454,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
|
|||||||
}
|
}
|
||||||
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
|
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
|
||||||
CISTPL_DEVICE_GEO, devgeo)) {
|
CISTPL_DEVICE_GEO, devgeo)) {
|
||||||
ds_dev_dbg(0, &p_dev->dev,
|
dev_dbg(&p_dev->dev,
|
||||||
"mem device geometry probably means "
|
"mem device geometry probably means "
|
||||||
"FUNCID_MEMORY\n");
|
"FUNCID_MEMORY\n");
|
||||||
p_dev->func_id = CISTPL_FUNCID_MEMORY;
|
p_dev->func_id = CISTPL_FUNCID_MEMORY;
|
||||||
@ -628,7 +510,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||||||
|
|
||||||
mutex_lock(&device_add_lock);
|
mutex_lock(&device_add_lock);
|
||||||
|
|
||||||
ds_dbg(3, "adding device to %d, function %d\n", s->sock, function);
|
pr_debug("adding device to %d, function %d\n", s->sock, function);
|
||||||
|
|
||||||
/* max of 4 devices per card */
|
/* max of 4 devices per card */
|
||||||
if (s->device_count == 4)
|
if (s->device_count == 4)
|
||||||
@ -654,7 +536,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||||||
p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
|
p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
|
||||||
if (!p_dev->devname)
|
if (!p_dev->devname)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
|
dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname);
|
||||||
|
|
||||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||||
|
|
||||||
@ -677,7 +559,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||||||
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
|
||||||
|
|
||||||
if (!p_dev->function_config) {
|
if (!p_dev->function_config) {
|
||||||
ds_dev_dbg(3, &p_dev->dev, "creating config_t\n");
|
dev_dbg(&p_dev->dev, "creating config_t\n");
|
||||||
p_dev->function_config = kzalloc(sizeof(struct config_t),
|
p_dev->function_config = kzalloc(sizeof(struct config_t),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!p_dev->function_config)
|
if (!p_dev->function_config)
|
||||||
@ -722,20 +604,20 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!(s->resource_setup_done)) {
|
if (!(s->resource_setup_done)) {
|
||||||
ds_dev_dbg(3, &s->dev,
|
dev_dbg(&s->dev,
|
||||||
"no resources available, delaying card_add\n");
|
"no resources available, delaying card_add\n");
|
||||||
return -EAGAIN; /* try again, but later... */
|
return -EAGAIN; /* try again, but later... */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcmcia_validate_mem(s)) {
|
if (pcmcia_validate_mem(s)) {
|
||||||
ds_dev_dbg(3, &s->dev, "validating mem resources failed, "
|
dev_dbg(&s->dev, "validating mem resources failed, "
|
||||||
"delaying card_add\n");
|
"delaying card_add\n");
|
||||||
return -EAGAIN; /* try again, but later... */
|
return -EAGAIN; /* try again, but later... */
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pccard_validate_cis(s, &no_chains);
|
ret = pccard_validate_cis(s, &no_chains);
|
||||||
if (ret || !no_chains) {
|
if (ret || !no_chains) {
|
||||||
ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
|
dev_dbg(&s->dev, "invalid CIS or invalid resources\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -756,7 +638,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work)
|
|||||||
{
|
{
|
||||||
struct pcmcia_socket *s =
|
struct pcmcia_socket *s =
|
||||||
container_of(work, struct pcmcia_socket, device_add);
|
container_of(work, struct pcmcia_socket, device_add);
|
||||||
ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock);
|
dev_dbg(&s->dev, "adding additional device to %d\n", s->sock);
|
||||||
pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
|
pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
|
||||||
s->pcmcia_state.device_add_pending = 0;
|
s->pcmcia_state.device_add_pending = 0;
|
||||||
s->pcmcia_state.mfc_pfc = 0;
|
s->pcmcia_state.mfc_pfc = 0;
|
||||||
@ -766,7 +648,7 @@ static int pcmcia_requery(struct device *dev, void * _data)
|
|||||||
{
|
{
|
||||||
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
|
||||||
if (!p_dev->dev.driver) {
|
if (!p_dev->dev.driver) {
|
||||||
ds_dev_dbg(1, dev, "update device information\n");
|
dev_dbg(dev, "update device information\n");
|
||||||
pcmcia_device_query(p_dev);
|
pcmcia_device_query(p_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,7 +662,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/* must be called with skt_mutex held */
|
/* must be called with skt_mutex held */
|
||||||
ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock);
|
dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock);
|
||||||
|
|
||||||
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
|
||||||
if (list_empty(&skt->devices_list))
|
if (list_empty(&skt->devices_list))
|
||||||
@ -835,7 +717,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
|
|||||||
if (!filename)
|
if (!filename)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
|
dev_dbg(&dev->dev, "trying to load CIS file %s\n", filename);
|
||||||
|
|
||||||
if (request_firmware(&fw, filename, &dev->dev) == 0) {
|
if (request_firmware(&fw, filename, &dev->dev) == 0) {
|
||||||
if (fw->size >= CISTPL_MAX_CIS_SIZE) {
|
if (fw->size >= CISTPL_MAX_CIS_SIZE) {
|
||||||
@ -953,14 +835,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
|
|||||||
* after it has re-checked that there is no possible module
|
* after it has re-checked that there is no possible module
|
||||||
* with a prod_id/manf_id/card_id match.
|
* with a prod_id/manf_id/card_id match.
|
||||||
*/
|
*/
|
||||||
ds_dev_dbg(0, &dev->dev,
|
dev_dbg(&dev->dev,
|
||||||
"skipping FUNC_ID match until userspace interaction\n");
|
"skipping FUNC_ID match until userspace interaction\n");
|
||||||
if (!dev->allow_func_id_match)
|
if (!dev->allow_func_id_match)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
|
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
|
||||||
ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n");
|
dev_dbg(&dev->dev, "device needs a fake CIS\n");
|
||||||
if (!dev->socket->fake_cis)
|
if (!dev->socket->fake_cis)
|
||||||
pcmcia_load_firmware(dev, did->cisfile);
|
pcmcia_load_firmware(dev, did->cisfile);
|
||||||
|
|
||||||
@ -992,9 +874,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
|
|||||||
/* match dynamic devices first */
|
/* match dynamic devices first */
|
||||||
spin_lock(&p_drv->dynids.lock);
|
spin_lock(&p_drv->dynids.lock);
|
||||||
list_for_each_entry(dynid, &p_drv->dynids.list, node) {
|
list_for_each_entry(dynid, &p_drv->dynids.list, node) {
|
||||||
ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
|
dev_dbg(dev, "trying to match to %s\n", drv->name);
|
||||||
if (pcmcia_devmatch(p_dev, &dynid->id)) {
|
if (pcmcia_devmatch(p_dev, &dynid->id)) {
|
||||||
ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
|
dev_dbg(dev, "matched to %s\n", drv->name);
|
||||||
spin_unlock(&p_drv->dynids.lock);
|
spin_unlock(&p_drv->dynids.lock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1004,15 +886,15 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
|
|||||||
#ifdef CONFIG_PCMCIA_IOCTL
|
#ifdef CONFIG_PCMCIA_IOCTL
|
||||||
/* matching by cardmgr */
|
/* matching by cardmgr */
|
||||||
if (p_dev->cardmgr == p_drv) {
|
if (p_dev->cardmgr == p_drv) {
|
||||||
ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name);
|
dev_dbg(dev, "cardmgr matched to %s\n", drv->name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (did && did->match_flags) {
|
while (did && did->match_flags) {
|
||||||
ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
|
dev_dbg(dev, "trying to match to %s\n", drv->name);
|
||||||
if (pcmcia_devmatch(p_dev, did)) {
|
if (pcmcia_devmatch(p_dev, did)) {
|
||||||
ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
|
dev_dbg(dev, "matched to %s\n", drv->name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
did++;
|
did++;
|
||||||
@ -1218,7 +1100,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
|
|||||||
if (p_dev->suspended)
|
if (p_dev->suspended)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ds_dev_dbg(2, dev, "suspending\n");
|
dev_dbg(dev, "suspending\n");
|
||||||
|
|
||||||
if (dev->driver)
|
if (dev->driver)
|
||||||
p_drv = to_pcmcia_drv(dev->driver);
|
p_drv = to_pcmcia_drv(dev->driver);
|
||||||
@ -1238,7 +1120,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p_dev->device_no == p_dev->func) {
|
if (p_dev->device_no == p_dev->func) {
|
||||||
ds_dev_dbg(2, dev, "releasing configuration\n");
|
dev_dbg(dev, "releasing configuration\n");
|
||||||
pcmcia_release_configuration(p_dev);
|
pcmcia_release_configuration(p_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,7 +1140,7 @@ static int pcmcia_dev_resume(struct device * dev)
|
|||||||
if (!p_dev->suspended)
|
if (!p_dev->suspended)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ds_dev_dbg(2, dev, "resuming\n");
|
dev_dbg(dev, "resuming\n");
|
||||||
|
|
||||||
if (dev->driver)
|
if (dev->driver)
|
||||||
p_drv = to_pcmcia_drv(dev->driver);
|
p_drv = to_pcmcia_drv(dev->driver);
|
||||||
@ -1267,7 +1149,7 @@ static int pcmcia_dev_resume(struct device * dev)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (p_dev->device_no == p_dev->func) {
|
if (p_dev->device_no == p_dev->func) {
|
||||||
ds_dev_dbg(2, dev, "requesting configuration\n");
|
dev_dbg(dev, "requesting configuration\n");
|
||||||
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
|
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
@ -1309,14 +1191,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
|
|||||||
|
|
||||||
static int pcmcia_bus_resume(struct pcmcia_socket *skt)
|
static int pcmcia_bus_resume(struct pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock);
|
dev_dbg(&skt->dev, "resuming socket %d\n", skt->sock);
|
||||||
bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
|
bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
|
static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock);
|
dev_dbg(&skt->dev, "suspending socket %d\n", skt->sock);
|
||||||
if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
|
if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
|
||||||
pcmcia_bus_suspend_callback)) {
|
pcmcia_bus_suspend_callback)) {
|
||||||
pcmcia_bus_resume(skt);
|
pcmcia_bus_resume(skt);
|
||||||
@ -1348,7 +1230,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
|
dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
|
||||||
event, priority, skt);
|
event, priority, skt);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -63,21 +63,6 @@
|
|||||||
#include "vg468.h"
|
#include "vg468.h"
|
||||||
#include "ricoh.h"
|
#include "ricoh.h"
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
static const char version[] =
|
|
||||||
"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
|
|
||||||
|
|
||||||
static int pc_debug;
|
|
||||||
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
|
|
||||||
#define debug(lvl, fmt, arg...) do { \
|
|
||||||
if (pc_debug > (lvl)) \
|
|
||||||
printk(KERN_DEBUG "i82365: " fmt , ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
#define debug(lvl, fmt, arg...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static irqreturn_t i365_count_irq(int, void *);
|
static irqreturn_t i365_count_irq(int, void *);
|
||||||
static inline int _check_irq(int irq, int flags)
|
static inline int _check_irq(int irq, int flags)
|
||||||
@ -501,13 +486,13 @@ static irqreturn_t i365_count_irq(int irq, void *dev)
|
|||||||
{
|
{
|
||||||
i365_get(irq_sock, I365_CSC);
|
i365_get(irq_sock, I365_CSC);
|
||||||
irq_hits++;
|
irq_hits++;
|
||||||
debug(2, "-> hit on irq %d\n", irq);
|
pr_debug("i82365: -> hit on irq %d\n", irq);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u_int __init test_irq(u_short sock, int irq)
|
static u_int __init test_irq(u_short sock, int irq)
|
||||||
{
|
{
|
||||||
debug(2, " testing ISA irq %d\n", irq);
|
pr_debug("i82365: testing ISA irq %d\n", irq);
|
||||||
if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan",
|
if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan",
|
||||||
i365_count_irq) != 0)
|
i365_count_irq) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -515,7 +500,7 @@ static u_int __init test_irq(u_short sock, int irq)
|
|||||||
msleep(10);
|
msleep(10);
|
||||||
if (irq_hits) {
|
if (irq_hits) {
|
||||||
free_irq(irq, i365_count_irq);
|
free_irq(irq, i365_count_irq);
|
||||||
debug(2, " spurious hit!\n");
|
pr_debug("i82365: spurious hit!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,7 +513,7 @@ static u_int __init test_irq(u_short sock, int irq)
|
|||||||
|
|
||||||
/* mask all interrupts */
|
/* mask all interrupts */
|
||||||
i365_set(sock, I365_CSCINT, 0);
|
i365_set(sock, I365_CSCINT, 0);
|
||||||
debug(2, " hits = %d\n", irq_hits);
|
pr_debug("i82365: hits = %d\n", irq_hits);
|
||||||
|
|
||||||
return (irq_hits != 1);
|
return (irq_hits != 1);
|
||||||
}
|
}
|
||||||
@ -854,7 +839,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
|
|||||||
u_long flags = 0;
|
u_long flags = 0;
|
||||||
int handled = 0;
|
int handled = 0;
|
||||||
|
|
||||||
debug(4, "pcic_interrupt(%d)\n", irq);
|
pr_debug("pcic_interrupt(%d)\n", irq);
|
||||||
|
|
||||||
for (j = 0; j < 20; j++) {
|
for (j = 0; j < 20; j++) {
|
||||||
active = 0;
|
active = 0;
|
||||||
@ -878,7 +863,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
|
|||||||
events |= (csc & I365_CSC_READY) ? SS_READY : 0;
|
events |= (csc & I365_CSC_READY) ? SS_READY : 0;
|
||||||
}
|
}
|
||||||
ISA_UNLOCK(i, flags);
|
ISA_UNLOCK(i, flags);
|
||||||
debug(2, "socket %d event 0x%02x\n", i, events);
|
pr_debug("socket %d event 0x%02x\n", i, events);
|
||||||
|
|
||||||
if (events)
|
if (events)
|
||||||
pcmcia_parse_events(&socket[i].socket, events);
|
pcmcia_parse_events(&socket[i].socket, events);
|
||||||
@ -890,7 +875,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
|
|||||||
if (j == 20)
|
if (j == 20)
|
||||||
printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
|
printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
|
||||||
|
|
||||||
debug(4, "interrupt done\n");
|
pr_debug("pcic_interrupt done\n");
|
||||||
return IRQ_RETVAL(handled);
|
return IRQ_RETVAL(handled);
|
||||||
} /* pcic_interrupt */
|
} /* pcic_interrupt */
|
||||||
|
|
||||||
@ -932,7 +917,7 @@ static int i365_get_status(u_short sock, u_int *value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(1, "GetStatus(%d) = %#4.4x\n", sock, *value);
|
pr_debug("GetStatus(%d) = %#4.4x\n", sock, *value);
|
||||||
return 0;
|
return 0;
|
||||||
} /* i365_get_status */
|
} /* i365_get_status */
|
||||||
|
|
||||||
@ -943,7 +928,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
|
|||||||
struct i82365_socket *t = &socket[sock];
|
struct i82365_socket *t = &socket[sock];
|
||||||
u_char reg;
|
u_char reg;
|
||||||
|
|
||||||
debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
||||||
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
|
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
|
||||||
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
||||||
|
|
||||||
@ -1052,7 +1037,7 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
|
|||||||
{
|
{
|
||||||
u_char map, ioctl;
|
u_char map, ioctl;
|
||||||
|
|
||||||
debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("SetIOMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
|
"%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
|
||||||
(unsigned long long)io->start, (unsigned long long)io->stop);
|
(unsigned long long)io->start, (unsigned long long)io->stop);
|
||||||
map = io->map;
|
map = io->map;
|
||||||
@ -1082,7 +1067,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
|
|||||||
u_short base, i;
|
u_short base, i;
|
||||||
u_char map;
|
u_char map;
|
||||||
|
|
||||||
debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
|
pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
|
||||||
"%#x)\n", sock, mem->map, mem->flags, mem->speed,
|
"%#x)\n", sock, mem->map, mem->flags, mem->speed,
|
||||||
(unsigned long long)mem->res->start,
|
(unsigned long long)mem->res->start,
|
||||||
(unsigned long long)mem->res->end, mem->card_start);
|
(unsigned long long)mem->res->end, mem->card_start);
|
||||||
|
@ -38,17 +38,6 @@
|
|||||||
|
|
||||||
#include "m32r_cfc.h"
|
#include "m32r_cfc.h"
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
static int m32r_cfc_debug;
|
|
||||||
module_param(m32r_cfc_debug, int, 0644);
|
|
||||||
#define debug(lvl, fmt, arg...) do { \
|
|
||||||
if (m32r_cfc_debug > (lvl)) \
|
|
||||||
printk(KERN_DEBUG "m32r_cfc: " fmt , ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
#define debug(n, args...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Poll status interval -- 0 means default to interrupt */
|
/* Poll status interval -- 0 means default to interrupt */
|
||||||
static int poll_interval = 0;
|
static int poll_interval = 0;
|
||||||
|
|
||||||
@ -123,7 +112,7 @@ void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
unsigned char *bp = (unsigned char *)buf;
|
unsigned char *bp = (unsigned char *)buf;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
|
pr_debug("m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
|
||||||
"size=%u, nmemb=%d, flag=%d\n",
|
"size=%u, nmemb=%d, flag=%d\n",
|
||||||
sock, port, buf, size, nmemb, flag);
|
sock, port, buf, size, nmemb, flag);
|
||||||
|
|
||||||
@ -132,7 +121,7 @@ void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
|
printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
|
pr_debug("m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
|
||||||
|
|
||||||
spin_lock_irqsave(&pcc_lock, flags);
|
spin_lock_irqsave(&pcc_lock, flags);
|
||||||
/* read Byte */
|
/* read Byte */
|
||||||
@ -148,7 +137,7 @@ void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
unsigned short *bp = (unsigned short *)buf;
|
unsigned short *bp = (unsigned short *)buf;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
|
pr_debug("m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
|
||||||
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
|
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
|
||||||
sock, port, buf, size, nmemb, flag);
|
sock, port, buf, size, nmemb, flag);
|
||||||
|
|
||||||
@ -163,7 +152,7 @@ void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
printk("m32r_cfc:ioread_word null port :%#lx\n",port);
|
printk("m32r_cfc:ioread_word null port :%#lx\n",port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
|
pr_debug("m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
|
||||||
|
|
||||||
spin_lock_irqsave(&pcc_lock, flags);
|
spin_lock_irqsave(&pcc_lock, flags);
|
||||||
/* read Word */
|
/* read Word */
|
||||||
@ -179,7 +168,7 @@ void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
unsigned char *bp = (unsigned char *)buf;
|
unsigned char *bp = (unsigned char *)buf;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
|
pr_debug("m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
|
||||||
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
|
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
|
||||||
sock, port, buf, size, nmemb, flag);
|
sock, port, buf, size, nmemb, flag);
|
||||||
|
|
||||||
@ -189,7 +178,7 @@ void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
|
printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
|
pr_debug("m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
|
||||||
|
|
||||||
spin_lock_irqsave(&pcc_lock, flags);
|
spin_lock_irqsave(&pcc_lock, flags);
|
||||||
while (nmemb--)
|
while (nmemb--)
|
||||||
@ -204,7 +193,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
unsigned short *bp = (unsigned short *)buf;
|
unsigned short *bp = (unsigned short *)buf;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
|
pr_debug("m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
|
||||||
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
|
"buf=%p, size=%u, nmemb=%d, flag=%d\n",
|
||||||
sock, port, buf, size, nmemb, flag);
|
sock, port, buf, size, nmemb, flag);
|
||||||
|
|
||||||
@ -226,7 +215,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
debug(3, "m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
|
pr_debug("m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
|
||||||
|
|
||||||
spin_lock_irqsave(&pcc_lock, flags);
|
spin_lock_irqsave(&pcc_lock, flags);
|
||||||
while (nmemb--)
|
while (nmemb--)
|
||||||
@ -262,7 +251,7 @@ static struct timer_list poll_timer;
|
|||||||
static unsigned int pcc_get(u_short sock, unsigned int reg)
|
static unsigned int pcc_get(u_short sock, unsigned int reg)
|
||||||
{
|
{
|
||||||
unsigned int val = inw(reg);
|
unsigned int val = inw(reg);
|
||||||
debug(3, "m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
|
pr_debug("m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +259,7 @@ static unsigned int pcc_get(u_short sock, unsigned int reg)
|
|||||||
static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
|
static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
|
||||||
{
|
{
|
||||||
outw(data, reg);
|
outw(data, reg);
|
||||||
debug(3, "m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
|
pr_debug("m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
@ -286,14 +275,14 @@ static int __init is_alive(u_short sock)
|
|||||||
{
|
{
|
||||||
unsigned int stat;
|
unsigned int stat;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: is_alive:\n");
|
pr_debug("m32r_cfc: is_alive:\n");
|
||||||
|
|
||||||
printk("CF: ");
|
printk("CF: ");
|
||||||
stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
|
stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
|
||||||
if (!stat)
|
if (!stat)
|
||||||
printk("No ");
|
printk("No ");
|
||||||
printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
|
printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
|
||||||
debug(3, "m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
|
pr_debug("m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -303,7 +292,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
|
|||||||
{
|
{
|
||||||
pcc_socket_t *t = &socket[pcc_sockets];
|
pcc_socket_t *t = &socket[pcc_sockets];
|
||||||
|
|
||||||
debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
|
pr_debug("m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
|
||||||
"mapaddr=%#lx, ioaddr=%08x\n",
|
"mapaddr=%#lx, ioaddr=%08x\n",
|
||||||
base, irq, mapaddr, ioaddr);
|
base, irq, mapaddr, ioaddr);
|
||||||
|
|
||||||
@ -358,7 +347,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
|
|||||||
/* eject interrupt */
|
/* eject interrupt */
|
||||||
request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
|
request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
|
||||||
#endif
|
#endif
|
||||||
debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
|
pr_debug("m32r_cfc: enable CFMSK, RDYSEL\n");
|
||||||
pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
|
pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
|
||||||
#endif /* CONFIG_PLAT_USRV */
|
#endif /* CONFIG_PLAT_USRV */
|
||||||
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
|
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
|
||||||
@ -378,26 +367,26 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
|
|||||||
u_int events = 0;
|
u_int events = 0;
|
||||||
int handled = 0;
|
int handled = 0;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
|
pr_debug("m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
|
||||||
for (i = 0; i < pcc_sockets; i++) {
|
for (i = 0; i < pcc_sockets; i++) {
|
||||||
if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
|
if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
handled = 1;
|
handled = 1;
|
||||||
debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
|
pr_debug("m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
|
||||||
i, irq);
|
i, irq);
|
||||||
events |= SS_DETECT; /* insert or eject */
|
events |= SS_DETECT; /* insert or eject */
|
||||||
if (events)
|
if (events)
|
||||||
pcmcia_parse_events(&socket[i].socket, events);
|
pcmcia_parse_events(&socket[i].socket, events);
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_interrupt: done\n");
|
pr_debug("m32r_cfc: pcc_interrupt: done\n");
|
||||||
|
|
||||||
return IRQ_RETVAL(handled);
|
return IRQ_RETVAL(handled);
|
||||||
} /* pcc_interrupt */
|
} /* pcc_interrupt */
|
||||||
|
|
||||||
static void pcc_interrupt_wrapper(u_long data)
|
static void pcc_interrupt_wrapper(u_long data)
|
||||||
{
|
{
|
||||||
debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
|
pr_debug("m32r_cfc: pcc_interrupt_wrapper:\n");
|
||||||
pcc_interrupt(0, NULL);
|
pcc_interrupt(0, NULL);
|
||||||
init_timer(&poll_timer);
|
init_timer(&poll_timer);
|
||||||
poll_timer.expires = jiffies + poll_interval;
|
poll_timer.expires = jiffies + poll_interval;
|
||||||
@ -410,17 +399,17 @@ static int _pcc_get_status(u_short sock, u_int *value)
|
|||||||
{
|
{
|
||||||
u_int status;
|
u_int status;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: _pcc_get_status:\n");
|
pr_debug("m32r_cfc: _pcc_get_status:\n");
|
||||||
status = pcc_get(sock, (unsigned int)PLD_CFSTS);
|
status = pcc_get(sock, (unsigned int)PLD_CFSTS);
|
||||||
*value = (status) ? SS_DETECT : 0;
|
*value = (status) ? SS_DETECT : 0;
|
||||||
debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
|
pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
|
||||||
|
|
||||||
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
|
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
|
||||||
if ( status ) {
|
if ( status ) {
|
||||||
/* enable CF power */
|
/* enable CF power */
|
||||||
status = inw((unsigned int)PLD_CPCR);
|
status = inw((unsigned int)PLD_CPCR);
|
||||||
if (!(status & PLD_CPCR_CF)) {
|
if (!(status & PLD_CPCR_CF)) {
|
||||||
debug(3, "m32r_cfc: _pcc_get_status: "
|
pr_debug("m32r_cfc: _pcc_get_status: "
|
||||||
"power on (CPCR=0x%08x)\n", status);
|
"power on (CPCR=0x%08x)\n", status);
|
||||||
status |= PLD_CPCR_CF;
|
status |= PLD_CPCR_CF;
|
||||||
outw(status, (unsigned int)PLD_CPCR);
|
outw(status, (unsigned int)PLD_CPCR);
|
||||||
@ -439,7 +428,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
|
|||||||
status &= ~PLD_CPCR_CF;
|
status &= ~PLD_CPCR_CF;
|
||||||
outw(status, (unsigned int)PLD_CPCR);
|
outw(status, (unsigned int)PLD_CPCR);
|
||||||
udelay(100);
|
udelay(100);
|
||||||
debug(3, "m32r_cfc: _pcc_get_status: "
|
pr_debug("m32r_cfc: _pcc_get_status: "
|
||||||
"power off (CPCR=0x%08x)\n", status);
|
"power off (CPCR=0x%08x)\n", status);
|
||||||
}
|
}
|
||||||
#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
|
#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
|
||||||
@ -465,13 +454,13 @@ static int _pcc_get_status(u_short sock, u_int *value)
|
|||||||
/* disable CF power */
|
/* disable CF power */
|
||||||
pcc_set(sock, (unsigned int)PLD_CPCR, 0);
|
pcc_set(sock, (unsigned int)PLD_CPCR, 0);
|
||||||
udelay(100);
|
udelay(100);
|
||||||
debug(3, "m32r_cfc: _pcc_get_status: "
|
pr_debug("m32r_cfc: _pcc_get_status: "
|
||||||
"power off (CPCR=0x%08x)\n", status);
|
"power off (CPCR=0x%08x)\n", status);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#error no platform configuration
|
#error no platform configuration
|
||||||
#endif
|
#endif
|
||||||
debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
|
pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
|
||||||
sock, *value);
|
sock, *value);
|
||||||
return 0;
|
return 0;
|
||||||
} /* _get_status */
|
} /* _get_status */
|
||||||
@ -480,7 +469,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
|
|||||||
|
|
||||||
static int _pcc_set_socket(u_short sock, socket_state_t *state)
|
static int _pcc_set_socket(u_short sock, socket_state_t *state)
|
||||||
{
|
{
|
||||||
debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
pr_debug("m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
||||||
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
|
"io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
|
||||||
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
||||||
|
|
||||||
@ -492,41 +481,39 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (state->flags & SS_RESET) {
|
if (state->flags & SS_RESET) {
|
||||||
debug(3, ":RESET\n");
|
pr_debug(":RESET\n");
|
||||||
pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
|
pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
|
||||||
}else{
|
}else{
|
||||||
pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
|
pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
|
||||||
}
|
}
|
||||||
if (state->flags & SS_OUTPUT_ENA){
|
if (state->flags & SS_OUTPUT_ENA){
|
||||||
debug(3, ":OUTPUT_ENA\n");
|
pr_debug(":OUTPUT_ENA\n");
|
||||||
/* bit clear */
|
/* bit clear */
|
||||||
pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
|
pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
|
||||||
} else {
|
} else {
|
||||||
pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
|
pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
if(state->flags & SS_IOCARD){
|
if(state->flags & SS_IOCARD){
|
||||||
debug(3, ":IOCARD");
|
pr_debug(":IOCARD");
|
||||||
}
|
}
|
||||||
if (state->flags & SS_PWR_AUTO) {
|
if (state->flags & SS_PWR_AUTO) {
|
||||||
debug(3, ":PWR_AUTO");
|
pr_debug(":PWR_AUTO");
|
||||||
}
|
}
|
||||||
if (state->csc_mask & SS_DETECT)
|
if (state->csc_mask & SS_DETECT)
|
||||||
debug(3, ":csc-SS_DETECT");
|
pr_debug(":csc-SS_DETECT");
|
||||||
if (state->flags & SS_IOCARD) {
|
if (state->flags & SS_IOCARD) {
|
||||||
if (state->csc_mask & SS_STSCHG)
|
if (state->csc_mask & SS_STSCHG)
|
||||||
debug(3, ":STSCHG");
|
pr_debug(":STSCHG");
|
||||||
} else {
|
} else {
|
||||||
if (state->csc_mask & SS_BATDEAD)
|
if (state->csc_mask & SS_BATDEAD)
|
||||||
debug(3, ":BATDEAD");
|
pr_debug(":BATDEAD");
|
||||||
if (state->csc_mask & SS_BATWARN)
|
if (state->csc_mask & SS_BATWARN)
|
||||||
debug(3, ":BATWARN");
|
pr_debug(":BATWARN");
|
||||||
if (state->csc_mask & SS_READY)
|
if (state->csc_mask & SS_READY)
|
||||||
debug(3, ":READY");
|
pr_debug(":READY");
|
||||||
}
|
}
|
||||||
debug(3, "\n");
|
pr_debug("\n");
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* _set_socket */
|
} /* _set_socket */
|
||||||
|
|
||||||
@ -536,7 +523,7 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
|
|||||||
{
|
{
|
||||||
u_char map;
|
u_char map;
|
||||||
|
|
||||||
debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#llx-%#llx)\n", sock, io->map, io->flags,
|
"%#llx-%#llx)\n", sock, io->map, io->flags,
|
||||||
io->speed, (unsigned long long)io->start,
|
io->speed, (unsigned long long)io->start,
|
||||||
(unsigned long long)io->stop);
|
(unsigned long long)io->stop);
|
||||||
@ -554,7 +541,7 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
|
|||||||
u_long addr;
|
u_long addr;
|
||||||
pcc_socket_t *t = &socket[sock];
|
pcc_socket_t *t = &socket[sock];
|
||||||
|
|
||||||
debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#llx, %#x)\n", sock, map, mem->flags,
|
"%#llx, %#x)\n", sock, map, mem->flags,
|
||||||
mem->speed, (unsigned long long)mem->static_start,
|
mem->speed, (unsigned long long)mem->static_start,
|
||||||
mem->card_start);
|
mem->card_start);
|
||||||
@ -640,11 +627,11 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
|
|||||||
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
||||||
|
|
||||||
if (socket[sock].flags & IS_ALIVE) {
|
if (socket[sock].flags & IS_ALIVE) {
|
||||||
debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
|
dev_dbg(&s->dev, "pcc_get_status: sock(%d) -EINVAL\n", sock);
|
||||||
*value = 0;
|
*value = 0;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
|
dev_dbg(&s->dev, "pcc_get_status: sock(%d)\n", sock);
|
||||||
LOCKED(_pcc_get_status(sock, value));
|
LOCKED(_pcc_get_status(sock, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,10 +640,10 @@ static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
|
|||||||
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
||||||
|
|
||||||
if (socket[sock].flags & IS_ALIVE) {
|
if (socket[sock].flags & IS_ALIVE) {
|
||||||
debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
|
dev_dbg(&s->dev, "pcc_set_socket: sock(%d) -EINVAL\n", sock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
|
dev_dbg(&s->dev, "pcc_set_socket: sock(%d)\n", sock);
|
||||||
LOCKED(_pcc_set_socket(sock, state));
|
LOCKED(_pcc_set_socket(sock, state));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,10 +652,10 @@ static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
|
|||||||
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
||||||
|
|
||||||
if (socket[sock].flags & IS_ALIVE) {
|
if (socket[sock].flags & IS_ALIVE) {
|
||||||
debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
|
dev_dbg(&s->dev, "pcc_set_io_map: sock(%d) -EINVAL\n", sock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
|
dev_dbg(&s->dev, "pcc_set_io_map: sock(%d)\n", sock);
|
||||||
LOCKED(_pcc_set_io_map(sock, io));
|
LOCKED(_pcc_set_io_map(sock, io));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,16 +664,16 @@ static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
|
|||||||
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
|
||||||
|
|
||||||
if (socket[sock].flags & IS_ALIVE) {
|
if (socket[sock].flags & IS_ALIVE) {
|
||||||
debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
|
dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
|
dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d)\n", sock);
|
||||||
LOCKED(_pcc_set_mem_map(sock, mem));
|
LOCKED(_pcc_set_mem_map(sock, mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcc_init(struct pcmcia_socket *s)
|
static int pcc_init(struct pcmcia_socket *s)
|
||||||
{
|
{
|
||||||
debug(3, "m32r_cfc: pcc_init()\n");
|
dev_dbg(&s->dev, "pcc_init()\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,16 +45,6 @@
|
|||||||
|
|
||||||
#define PCC_DEBUG_DBEX
|
#define PCC_DEBUG_DBEX
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
static int m32r_pcc_debug;
|
|
||||||
module_param(m32r_pcc_debug, int, 0644);
|
|
||||||
#define debug(lvl, fmt, arg...) do { \
|
|
||||||
if (m32r_pcc_debug > (lvl)) \
|
|
||||||
printk(KERN_DEBUG "m32r_pcc: " fmt , ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
#define debug(n, args...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Poll status interval -- 0 means default to interrupt */
|
/* Poll status interval -- 0 means default to interrupt */
|
||||||
static int poll_interval = 0;
|
static int poll_interval = 0;
|
||||||
@ -358,7 +348,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
|
|||||||
u_int events, active;
|
u_int events, active;
|
||||||
int handled = 0;
|
int handled = 0;
|
||||||
|
|
||||||
debug(4, "m32r: pcc_interrupt(%d)\n", irq);
|
pr_debug("m32r_pcc: pcc_interrupt(%d)\n", irq);
|
||||||
|
|
||||||
for (j = 0; j < 20; j++) {
|
for (j = 0; j < 20; j++) {
|
||||||
active = 0;
|
active = 0;
|
||||||
@ -369,13 +359,14 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
|
|||||||
handled = 1;
|
handled = 1;
|
||||||
irc = pcc_get(i, PCIRC);
|
irc = pcc_get(i, PCIRC);
|
||||||
irc >>=16;
|
irc >>=16;
|
||||||
debug(2, "m32r-pcc:interrupt: socket %d pcirc 0x%02x ", i, irc);
|
pr_debug("m32r_pcc: interrupt: socket %d pcirc 0x%02x ",
|
||||||
|
i, irc);
|
||||||
if (!irc)
|
if (!irc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
events = (irc) ? SS_DETECT : 0;
|
events = (irc) ? SS_DETECT : 0;
|
||||||
events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
|
events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
|
||||||
debug(2, " event 0x%02x\n", events);
|
pr_debug("m32r_pcc: event 0x%02x\n", events);
|
||||||
|
|
||||||
if (events)
|
if (events)
|
||||||
pcmcia_parse_events(&socket[i].socket, events);
|
pcmcia_parse_events(&socket[i].socket, events);
|
||||||
@ -388,7 +379,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
|
|||||||
if (j == 20)
|
if (j == 20)
|
||||||
printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
|
printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
|
||||||
|
|
||||||
debug(4, "m32r-pcc: interrupt done\n");
|
pr_debug("m32r_pcc: interrupt done\n");
|
||||||
|
|
||||||
return IRQ_RETVAL(handled);
|
return IRQ_RETVAL(handled);
|
||||||
} /* pcc_interrupt */
|
} /* pcc_interrupt */
|
||||||
@ -422,7 +413,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
|
|||||||
status = pcc_get(sock,PCCSIGCR);
|
status = pcc_get(sock,PCCSIGCR);
|
||||||
*value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
|
*value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
|
||||||
|
|
||||||
debug(3, "m32r-pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
|
pr_debug("m32r_pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
|
||||||
return 0;
|
return 0;
|
||||||
} /* _get_status */
|
} /* _get_status */
|
||||||
|
|
||||||
@ -432,7 +423,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
|
|||||||
{
|
{
|
||||||
u_long reg = 0;
|
u_long reg = 0;
|
||||||
|
|
||||||
debug(3, "m32r-pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
pr_debug("m32r_pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
||||||
"io_irq %d, csc_mask %#2.2x)", sock, state->flags,
|
"io_irq %d, csc_mask %#2.2x)", sock, state->flags,
|
||||||
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
||||||
|
|
||||||
@ -448,11 +439,11 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state->flags & SS_RESET) {
|
if (state->flags & SS_RESET) {
|
||||||
debug(3, ":RESET\n");
|
pr_debug("m32r_pcc: :RESET\n");
|
||||||
reg |= PCCSIGCR_CRST;
|
reg |= PCCSIGCR_CRST;
|
||||||
}
|
}
|
||||||
if (state->flags & SS_OUTPUT_ENA){
|
if (state->flags & SS_OUTPUT_ENA){
|
||||||
debug(3, ":OUTPUT_ENA\n");
|
pr_debug("m32r_pcc: :OUTPUT_ENA\n");
|
||||||
/* bit clear */
|
/* bit clear */
|
||||||
} else {
|
} else {
|
||||||
reg |= PCCSIGCR_SEN;
|
reg |= PCCSIGCR_SEN;
|
||||||
@ -460,28 +451,26 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
|
|||||||
|
|
||||||
pcc_set(sock,PCCSIGCR,reg);
|
pcc_set(sock,PCCSIGCR,reg);
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
if(state->flags & SS_IOCARD){
|
if(state->flags & SS_IOCARD){
|
||||||
debug(3, ":IOCARD");
|
pr_debug("m32r_pcc: :IOCARD");
|
||||||
}
|
}
|
||||||
if (state->flags & SS_PWR_AUTO) {
|
if (state->flags & SS_PWR_AUTO) {
|
||||||
debug(3, ":PWR_AUTO");
|
pr_debug("m32r_pcc: :PWR_AUTO");
|
||||||
}
|
}
|
||||||
if (state->csc_mask & SS_DETECT)
|
if (state->csc_mask & SS_DETECT)
|
||||||
debug(3, ":csc-SS_DETECT");
|
pr_debug("m32r_pcc: :csc-SS_DETECT");
|
||||||
if (state->flags & SS_IOCARD) {
|
if (state->flags & SS_IOCARD) {
|
||||||
if (state->csc_mask & SS_STSCHG)
|
if (state->csc_mask & SS_STSCHG)
|
||||||
debug(3, ":STSCHG");
|
pr_debug("m32r_pcc: :STSCHG");
|
||||||
} else {
|
} else {
|
||||||
if (state->csc_mask & SS_BATDEAD)
|
if (state->csc_mask & SS_BATDEAD)
|
||||||
debug(3, ":BATDEAD");
|
pr_debug("m32r_pcc: :BATDEAD");
|
||||||
if (state->csc_mask & SS_BATWARN)
|
if (state->csc_mask & SS_BATWARN)
|
||||||
debug(3, ":BATWARN");
|
pr_debug("m32r_pcc: :BATWARN");
|
||||||
if (state->csc_mask & SS_READY)
|
if (state->csc_mask & SS_READY)
|
||||||
debug(3, ":READY");
|
pr_debug("m32r_pcc: :READY");
|
||||||
}
|
}
|
||||||
debug(3, "\n");
|
pr_debug("m32r_pcc: \n");
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* _set_socket */
|
} /* _set_socket */
|
||||||
|
|
||||||
@ -491,7 +480,7 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
|
|||||||
{
|
{
|
||||||
u_char map;
|
u_char map;
|
||||||
|
|
||||||
debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("m32r_pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#llx-%#llx)\n", sock, io->map, io->flags,
|
"%#llx-%#llx)\n", sock, io->map, io->flags,
|
||||||
io->speed, (unsigned long long)io->start,
|
io->speed, (unsigned long long)io->start,
|
||||||
(unsigned long long)io->stop);
|
(unsigned long long)io->stop);
|
||||||
@ -515,7 +504,7 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("m32r_pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#llx, %#x)\n", sock, map, mem->flags,
|
"%#llx, %#x)\n", sock, map, mem->flags,
|
||||||
mem->speed, (unsigned long long)mem->static_start,
|
mem->speed, (unsigned long long)mem->static_start,
|
||||||
mem->card_start);
|
mem->card_start);
|
||||||
@ -662,7 +651,7 @@ static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
|
|||||||
|
|
||||||
static int pcc_init(struct pcmcia_socket *s)
|
static int pcc_init(struct pcmcia_socket *s)
|
||||||
{
|
{
|
||||||
debug(4, "m32r-pcc: init call\n");
|
pr_debug("m32r_pcc: init call\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,14 +64,6 @@
|
|||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
#include <pcmcia/ss.h>
|
#include <pcmcia/ss.h>
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
static int pc_debug;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
|
|
||||||
#else
|
|
||||||
#define dprintk(args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
|
#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
|
||||||
#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
|
#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
|
||||||
|
|
||||||
@ -565,7 +557,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
|
|||||||
unsigned int i, events, pscr, pipr, per;
|
unsigned int i, events, pscr, pipr, per;
|
||||||
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
|
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
|
||||||
|
|
||||||
dprintk("Interrupt!\n");
|
pr_debug("m8xx_pcmcia: Interrupt!\n");
|
||||||
/* get interrupt sources */
|
/* get interrupt sources */
|
||||||
|
|
||||||
pscr = in_be32(&pcmcia->pcmc_pscr);
|
pscr = in_be32(&pcmcia->pcmc_pscr);
|
||||||
@ -614,7 +606,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
|
|||||||
|
|
||||||
/* call the handler */
|
/* call the handler */
|
||||||
|
|
||||||
dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
|
pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, "
|
||||||
"pipr = 0x%08x\n", i, events, pscr, pipr);
|
"pipr = 0x%08x\n", i, events, pscr, pipr);
|
||||||
|
|
||||||
if (events) {
|
if (events) {
|
||||||
@ -641,7 +633,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
|
|||||||
/* clear the interrupt sources */
|
/* clear the interrupt sources */
|
||||||
out_be32(&pcmcia->pcmc_pscr, pscr);
|
out_be32(&pcmcia->pcmc_pscr, pscr);
|
||||||
|
|
||||||
dprintk("Interrupt done.\n");
|
pr_debug("m8xx_pcmcia: Interrupt done.\n");
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@ -815,7 +807,7 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
|
pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x\n", lsock, *value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,7 +820,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
|
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
|
||||||
|
|
||||||
dprintk("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
||||||
"io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
|
"io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
|
||||||
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
||||||
|
|
||||||
@ -974,7 +966,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
|
|||||||
#define M8XX_SIZE (io->stop - io->start + 1)
|
#define M8XX_SIZE (io->stop - io->start + 1)
|
||||||
#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
|
#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
|
||||||
|
|
||||||
dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
|
"%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
|
||||||
io->speed, (unsigned long long)io->start,
|
io->speed, (unsigned long long)io->start,
|
||||||
(unsigned long long)io->stop);
|
(unsigned long long)io->stop);
|
||||||
@ -988,7 +980,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
|
|||||||
|
|
||||||
if (io->flags & MAP_ACTIVE) {
|
if (io->flags & MAP_ACTIVE) {
|
||||||
|
|
||||||
dprintk("io->flags & MAP_ACTIVE\n");
|
pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE\n");
|
||||||
|
|
||||||
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
|
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
|
||||||
+ (lsock * PCMCIA_IO_WIN_NO) + io->map;
|
+ (lsock * PCMCIA_IO_WIN_NO) + io->map;
|
||||||
@ -1018,8 +1010,8 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
|
|||||||
|
|
||||||
out_be32(&w->or, reg);
|
out_be32(&w->or, reg);
|
||||||
|
|
||||||
dprintk("Socket %u: Mapped io window %u at %#8.8x, "
|
pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at "
|
||||||
"OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
|
"%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
|
||||||
} else {
|
} else {
|
||||||
/* shutdown IO window */
|
/* shutdown IO window */
|
||||||
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
|
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
|
||||||
@ -1033,14 +1025,14 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
|
|||||||
out_be32(&w->or, 0); /* turn off window */
|
out_be32(&w->or, 0); /* turn off window */
|
||||||
out_be32(&w->br, 0); /* turn off base address */
|
out_be32(&w->br, 0); /* turn off base address */
|
||||||
|
|
||||||
dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
|
pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at "
|
||||||
"OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
|
"%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the struct and modify the copy */
|
/* copy the struct and modify the copy */
|
||||||
s->io_win[io->map] = *io;
|
s->io_win[io->map] = *io;
|
||||||
s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
|
s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
|
||||||
dprintk("SetIOMap exit\n");
|
pr_debug("m8xx_pcmcia: SetIOMap exit\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1055,7 +1047,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
|
|||||||
unsigned int reg, winnr;
|
unsigned int reg, winnr;
|
||||||
pcmconf8xx_t *pcmcia = s->pcmcia;
|
pcmconf8xx_t *pcmcia = s->pcmcia;
|
||||||
|
|
||||||
dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
|
"%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
|
||||||
mem->speed, (unsigned long long)mem->static_start,
|
mem->speed, (unsigned long long)mem->static_start,
|
||||||
mem->card_start);
|
mem->card_start);
|
||||||
@ -1098,7 +1090,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
|
|||||||
|
|
||||||
out_be32(&w->or, reg);
|
out_be32(&w->or, reg);
|
||||||
|
|
||||||
dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
|
pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, "
|
||||||
"OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
|
"OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
|
||||||
|
|
||||||
if (mem->flags & MAP_ACTIVE) {
|
if (mem->flags & MAP_ACTIVE) {
|
||||||
@ -1108,7 +1100,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
|
|||||||
+ mem->card_start;
|
+ mem->card_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
|
pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
|
"%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
|
||||||
mem->speed, (unsigned long long)mem->static_start,
|
mem->speed, (unsigned long long)mem->static_start,
|
||||||
mem->card_start);
|
mem->card_start);
|
||||||
@ -1129,7 +1121,7 @@ static int m8xx_sock_init(struct pcmcia_socket *sock)
|
|||||||
pccard_io_map io = { 0, 0, 0, 0, 1 };
|
pccard_io_map io = { 0, 0, 0, 0, 1 };
|
||||||
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
|
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
dprintk("sock_init(%d)\n", s);
|
pr_debug("m8xx_pcmcia: sock_init(%d)\n", s);
|
||||||
|
|
||||||
m8xx_set_socket(sock, &dead_socket);
|
m8xx_set_socket(sock, &dead_socket);
|
||||||
for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
|
for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
|
||||||
|
@ -30,28 +30,6 @@
|
|||||||
#ifndef _LINUX_O2MICRO_H
|
#ifndef _LINUX_O2MICRO_H
|
||||||
#define _LINUX_O2MICRO_H
|
#define _LINUX_O2MICRO_H
|
||||||
|
|
||||||
#ifndef PCI_VENDOR_ID_O2
|
|
||||||
#define PCI_VENDOR_ID_O2 0x1217
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_O2_6729
|
|
||||||
#define PCI_DEVICE_ID_O2_6729 0x6729
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_O2_6730
|
|
||||||
#define PCI_DEVICE_ID_O2_6730 0x673a
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_O2_6832
|
|
||||||
#define PCI_DEVICE_ID_O2_6832 0x6832
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_O2_6836
|
|
||||||
#define PCI_DEVICE_ID_O2_6836 0x6836
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_O2_6812
|
|
||||||
#define PCI_DEVICE_ID_O2_6812 0x6872
|
|
||||||
#endif
|
|
||||||
#ifndef PCI_DEVICE_ID_O2_6933
|
|
||||||
#define PCI_DEVICE_ID_O2_6933 0x6933
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Additional PCI configuration registers */
|
/* Additional PCI configuration registers */
|
||||||
|
|
||||||
#define O2_MUX_CONTROL 0x90 /* 32 bit */
|
#define O2_MUX_CONTROL 0x90 /* 32 bit */
|
||||||
|
@ -58,17 +58,6 @@ typedef struct user_info_t {
|
|||||||
} user_info_t;
|
} user_info_t;
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
extern int ds_pc_debug;
|
|
||||||
|
|
||||||
#define ds_dbg(lvl, fmt, arg...) do { \
|
|
||||||
if (ds_pc_debug >= lvl) \
|
|
||||||
printk(KERN_DEBUG "ds: " fmt , ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
|
static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
|
||||||
unsigned int function)
|
unsigned int function)
|
||||||
{
|
{
|
||||||
@ -229,6 +218,61 @@ static int pcmcia_adjust_resource_info(adjust_t *adj)
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** pcmcia_get_window
|
||||||
|
*/
|
||||||
|
static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
|
||||||
|
window_handle_t wh, win_req_t *req)
|
||||||
|
{
|
||||||
|
pccard_mem_map *win;
|
||||||
|
window_handle_t w;
|
||||||
|
|
||||||
|
wh--;
|
||||||
|
if (!s || !(s->state & SOCKET_PRESENT))
|
||||||
|
return -ENODEV;
|
||||||
|
if (wh >= MAX_WIN)
|
||||||
|
return -EINVAL;
|
||||||
|
for (w = wh; w < MAX_WIN; w++)
|
||||||
|
if (s->state & SOCKET_WIN_REQ(w))
|
||||||
|
break;
|
||||||
|
if (w == MAX_WIN)
|
||||||
|
return -EINVAL;
|
||||||
|
win = &s->win[w];
|
||||||
|
req->Base = win->res->start;
|
||||||
|
req->Size = win->res->end - win->res->start + 1;
|
||||||
|
req->AccessSpeed = win->speed;
|
||||||
|
req->Attributes = 0;
|
||||||
|
if (win->flags & MAP_ATTRIB)
|
||||||
|
req->Attributes |= WIN_MEMORY_TYPE_AM;
|
||||||
|
if (win->flags & MAP_ACTIVE)
|
||||||
|
req->Attributes |= WIN_ENABLE;
|
||||||
|
if (win->flags & MAP_16BIT)
|
||||||
|
req->Attributes |= WIN_DATA_WIDTH_16;
|
||||||
|
if (win->flags & MAP_USE_WAIT)
|
||||||
|
req->Attributes |= WIN_USE_WAIT;
|
||||||
|
|
||||||
|
*wh_out = w + 1;
|
||||||
|
return 0;
|
||||||
|
} /* pcmcia_get_window */
|
||||||
|
|
||||||
|
|
||||||
|
/** pcmcia_get_mem_page
|
||||||
|
*
|
||||||
|
* Change the card address of an already open memory window.
|
||||||
|
*/
|
||||||
|
static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
|
||||||
|
memreq_t *req)
|
||||||
|
{
|
||||||
|
wh--;
|
||||||
|
if (wh >= MAX_WIN)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
req->Page = 0;
|
||||||
|
req->CardOffset = skt->win[wh].card_start;
|
||||||
|
return 0;
|
||||||
|
} /* pcmcia_get_mem_page */
|
||||||
|
|
||||||
|
|
||||||
/** pccard_get_status
|
/** pccard_get_status
|
||||||
*
|
*
|
||||||
* Get the current socket state bits. We don't support the latched
|
* Get the current socket state bits. We don't support the latched
|
||||||
@ -431,7 +475,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
|
|||||||
if (!s)
|
if (!s)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
|
pr_debug("bind_request(%d, '%s')\n", s->sock,
|
||||||
(char *)bind_info->dev_info);
|
(char *)bind_info->dev_info);
|
||||||
|
|
||||||
p_drv = get_pcmcia_driver(&bind_info->dev_info);
|
p_drv = get_pcmcia_driver(&bind_info->dev_info);
|
||||||
@ -623,7 +667,7 @@ static int ds_open(struct inode *inode, struct file *file)
|
|||||||
static int warning_printed = 0;
|
static int warning_printed = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ds_dbg(0, "ds_open(socket %d)\n", i);
|
pr_debug("ds_open(socket %d)\n", i);
|
||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
s = pcmcia_get_socket_by_nr(i);
|
s = pcmcia_get_socket_by_nr(i);
|
||||||
@ -685,7 +729,7 @@ static int ds_release(struct inode *inode, struct file *file)
|
|||||||
struct pcmcia_socket *s;
|
struct pcmcia_socket *s;
|
||||||
user_info_t *user, **link;
|
user_info_t *user, **link;
|
||||||
|
|
||||||
ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
|
pr_debug("ds_release(socket %d)\n", iminor(inode));
|
||||||
|
|
||||||
user = file->private_data;
|
user = file->private_data;
|
||||||
if (CHECK_USER(user))
|
if (CHECK_USER(user))
|
||||||
@ -719,7 +763,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
|
|||||||
user_info_t *user;
|
user_info_t *user;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
|
pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
|
||||||
|
|
||||||
if (count < 4)
|
if (count < 4)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -744,7 +788,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
|
|||||||
static ssize_t ds_write(struct file *file, const char __user *buf,
|
static ssize_t ds_write(struct file *file, const char __user *buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
|
pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
|
||||||
|
|
||||||
if (count != 4)
|
if (count != 4)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -762,7 +806,7 @@ static u_int ds_poll(struct file *file, poll_table *wait)
|
|||||||
struct pcmcia_socket *s;
|
struct pcmcia_socket *s;
|
||||||
user_info_t *user;
|
user_info_t *user;
|
||||||
|
|
||||||
ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
|
pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
|
||||||
|
|
||||||
user = file->private_data;
|
user = file->private_data;
|
||||||
if (CHECK_USER(user))
|
if (CHECK_USER(user))
|
||||||
@ -790,7 +834,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||||||
ds_ioctl_arg_t *buf;
|
ds_ioctl_arg_t *buf;
|
||||||
user_info_t *user;
|
user_info_t *user;
|
||||||
|
|
||||||
ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
|
pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
|
||||||
|
|
||||||
user = file->private_data;
|
user = file->private_data;
|
||||||
if (CHECK_USER(user))
|
if (CHECK_USER(user))
|
||||||
@ -809,13 +853,13 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||||||
|
|
||||||
if (cmd & IOC_IN) {
|
if (cmd & IOC_IN) {
|
||||||
if (!access_ok(VERIFY_READ, uarg, size)) {
|
if (!access_ok(VERIFY_READ, uarg, size)) {
|
||||||
ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
|
pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cmd & IOC_OUT) {
|
if (cmd & IOC_OUT) {
|
||||||
if (!access_ok(VERIFY_WRITE, uarg, size)) {
|
if (!access_ok(VERIFY_WRITE, uarg, size)) {
|
||||||
ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
|
pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -927,15 +971,15 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||||||
goto free_out;
|
goto free_out;
|
||||||
break;
|
break;
|
||||||
case DS_GET_FIRST_WINDOW:
|
case DS_GET_FIRST_WINDOW:
|
||||||
ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
|
ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
|
||||||
&buf->win_info.window);
|
&buf->win_info.window);
|
||||||
break;
|
break;
|
||||||
case DS_GET_NEXT_WINDOW:
|
case DS_GET_NEXT_WINDOW:
|
||||||
ret = pcmcia_get_window(s, &buf->win_info.handle,
|
ret = pcmcia_get_window(s, &buf->win_info.handle,
|
||||||
buf->win_info.handle->index + 1, &buf->win_info.window);
|
buf->win_info.handle + 1, &buf->win_info.window);
|
||||||
break;
|
break;
|
||||||
case DS_GET_MEM_PAGE:
|
case DS_GET_MEM_PAGE:
|
||||||
ret = pcmcia_get_mem_page(buf->win_info.handle,
|
ret = pcmcia_get_mem_page(s, buf->win_info.handle,
|
||||||
&buf->win_info.map);
|
&buf->win_info.map);
|
||||||
break;
|
break;
|
||||||
case DS_REPLACE_CIS:
|
case DS_REPLACE_CIS:
|
||||||
@ -962,7 +1006,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((err == 0) && (ret != 0)) {
|
if ((err == 0) && (ret != 0)) {
|
||||||
ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
|
pr_debug("ds_ioctl: ret = %d\n", ret);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case -ENODEV:
|
case -ENODEV:
|
||||||
case -EINVAL:
|
case -EINVAL:
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/ss.h>
|
#include <pcmcia/ss.h>
|
||||||
@ -43,21 +44,6 @@ static u8 pcmcia_used_irq[NR_IRQS];
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
extern int ds_pc_debug;
|
|
||||||
|
|
||||||
#define ds_dbg(skt, lvl, fmt, arg...) do { \
|
|
||||||
if (ds_pc_debug >= lvl) \
|
|
||||||
dev_printk(KERN_DEBUG, &skt->dev, \
|
|
||||||
"pcmcia_resource: " fmt, \
|
|
||||||
## arg); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** alloc_io_space
|
/** alloc_io_space
|
||||||
*
|
*
|
||||||
* Special stuff for managing IO windows, because they are scarce
|
* Special stuff for managing IO windows, because they are scarce
|
||||||
@ -72,14 +58,14 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
|
|||||||
align = (*base) ? (lines ? 1<<lines : 0) : 1;
|
align = (*base) ? (lines ? 1<<lines : 0) : 1;
|
||||||
if (align && (align < num)) {
|
if (align && (align < num)) {
|
||||||
if (*base) {
|
if (*base) {
|
||||||
ds_dbg(s, 0, "odd IO request: num %#x align %#x\n",
|
dev_dbg(&s->dev, "odd IO request: num %#x align %#x\n",
|
||||||
num, align);
|
num, align);
|
||||||
align = 0;
|
align = 0;
|
||||||
} else
|
} else
|
||||||
while (align && (align < num)) align <<= 1;
|
while (align && (align < num)) align <<= 1;
|
||||||
}
|
}
|
||||||
if (*base & ~(align-1)) {
|
if (*base & ~(align-1)) {
|
||||||
ds_dbg(s, 0, "odd IO request: base %#x align %#x\n",
|
dev_dbg(&s->dev, "odd IO request: base %#x align %#x\n",
|
||||||
*base, align);
|
*base, align);
|
||||||
align = 0;
|
align = 0;
|
||||||
}
|
}
|
||||||
@ -173,8 +159,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
|||||||
s = p_dev->socket;
|
s = p_dev->socket;
|
||||||
c = p_dev->function_config;
|
c = p_dev->function_config;
|
||||||
|
|
||||||
if (!(c->state & CONFIG_LOCKED))
|
if (!(c->state & CONFIG_LOCKED)) {
|
||||||
|
dev_dbg(&s->dev, "Configuration isnt't locked\n");
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
addr = (c->ConfigBase + reg->Offset) >> 1;
|
addr = (c->ConfigBase + reg->Offset) >> 1;
|
||||||
|
|
||||||
@ -188,6 +176,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
|||||||
pcmcia_write_cis_mem(s, 1, addr, 1, &val);
|
pcmcia_write_cis_mem(s, 1, addr, 1, &val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
dev_dbg(&s->dev, "Invalid conf register request\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -196,68 +185,21 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
|||||||
EXPORT_SYMBOL(pcmcia_access_configuration_register);
|
EXPORT_SYMBOL(pcmcia_access_configuration_register);
|
||||||
|
|
||||||
|
|
||||||
/** pcmcia_get_window
|
int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
|
||||||
*/
|
memreq_t *req)
|
||||||
int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
|
|
||||||
int idx, win_req_t *req)
|
|
||||||
{
|
{
|
||||||
window_t *win;
|
struct pcmcia_socket *s = p_dev->socket;
|
||||||
int w;
|
|
||||||
|
|
||||||
if (!s || !(s->state & SOCKET_PRESENT))
|
wh--;
|
||||||
return -ENODEV;
|
if (wh >= MAX_WIN)
|
||||||
for (w = idx; w < MAX_WIN; w++)
|
|
||||||
if (s->state & SOCKET_WIN_REQ(w))
|
|
||||||
break;
|
|
||||||
if (w == MAX_WIN)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
win = &s->win[w];
|
|
||||||
req->Base = win->ctl.res->start;
|
|
||||||
req->Size = win->ctl.res->end - win->ctl.res->start + 1;
|
|
||||||
req->AccessSpeed = win->ctl.speed;
|
|
||||||
req->Attributes = 0;
|
|
||||||
if (win->ctl.flags & MAP_ATTRIB)
|
|
||||||
req->Attributes |= WIN_MEMORY_TYPE_AM;
|
|
||||||
if (win->ctl.flags & MAP_ACTIVE)
|
|
||||||
req->Attributes |= WIN_ENABLE;
|
|
||||||
if (win->ctl.flags & MAP_16BIT)
|
|
||||||
req->Attributes |= WIN_DATA_WIDTH_16;
|
|
||||||
if (win->ctl.flags & MAP_USE_WAIT)
|
|
||||||
req->Attributes |= WIN_USE_WAIT;
|
|
||||||
*handle = win;
|
|
||||||
return 0;
|
|
||||||
} /* pcmcia_get_window */
|
|
||||||
EXPORT_SYMBOL(pcmcia_get_window);
|
|
||||||
|
|
||||||
|
|
||||||
/** pcmcia_get_mem_page
|
|
||||||
*
|
|
||||||
* Change the card address of an already open memory window.
|
|
||||||
*/
|
|
||||||
int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
|
|
||||||
{
|
|
||||||
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
|
|
||||||
return -EINVAL;
|
|
||||||
req->Page = 0;
|
|
||||||
req->CardOffset = win->ctl.card_start;
|
|
||||||
return 0;
|
|
||||||
} /* pcmcia_get_mem_page */
|
|
||||||
EXPORT_SYMBOL(pcmcia_get_mem_page);
|
|
||||||
|
|
||||||
|
|
||||||
int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
|
|
||||||
{
|
|
||||||
struct pcmcia_socket *s;
|
|
||||||
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
|
|
||||||
return -EINVAL;
|
|
||||||
s = win->sock;
|
|
||||||
if (req->Page != 0) {
|
if (req->Page != 0) {
|
||||||
ds_dbg(s, 0, "failure: requested page is zero\n");
|
dev_dbg(&s->dev, "failure: requested page is zero\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
win->ctl.card_start = req->CardOffset;
|
s->win[wh].card_start = req->CardOffset;
|
||||||
if (s->ops->set_mem_map(s, &win->ctl) != 0) {
|
if (s->ops->set_mem_map(s, &s->win[wh]) != 0) {
|
||||||
ds_dbg(s, 0, "failed to set_mem_map\n");
|
dev_dbg(&s->dev, "failed to set_mem_map\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -278,10 +220,14 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
|||||||
s = p_dev->socket;
|
s = p_dev->socket;
|
||||||
c = p_dev->function_config;
|
c = p_dev->function_config;
|
||||||
|
|
||||||
if (!(s->state & SOCKET_PRESENT))
|
if (!(s->state & SOCKET_PRESENT)) {
|
||||||
|
dev_dbg(&s->dev, "No card present\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
if (!(c->state & CONFIG_LOCKED))
|
}
|
||||||
|
if (!(c->state & CONFIG_LOCKED)) {
|
||||||
|
dev_dbg(&s->dev, "Configuration isnt't locked\n");
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
|
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
|
||||||
if (mod->Attributes & CONF_ENABLE_IRQ) {
|
if (mod->Attributes & CONF_ENABLE_IRQ) {
|
||||||
@ -295,7 +241,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
|
if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
|
||||||
ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
|
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +249,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
|||||||
if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
|
if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
|
||||||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
|
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
|
||||||
if (mod->Vpp1 != mod->Vpp2) {
|
if (mod->Vpp1 != mod->Vpp2) {
|
||||||
ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
|
dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
s->socket.Vpp = mod->Vpp1;
|
s->socket.Vpp = mod->Vpp1;
|
||||||
@ -314,7 +260,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
|
|||||||
}
|
}
|
||||||
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
|
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
|
||||||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
|
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
|
||||||
ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
|
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,11 +371,11 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
if (c->state & CONFIG_LOCKED)
|
if (c->state & CONFIG_LOCKED)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
if (c->irq.Attributes != req->Attributes) {
|
if (c->irq.Attributes != req->Attributes) {
|
||||||
ds_dbg(s, 0, "IRQ attributes must match assigned ones\n");
|
dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (s->irq.AssignedIRQ != req->AssignedIRQ) {
|
if (s->irq.AssignedIRQ != req->AssignedIRQ) {
|
||||||
ds_dbg(s, 0, "IRQ must match assigned one\n");
|
dev_dbg(&s->dev, "IRQ must match assigned one\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (--s->irq.Config == 0) {
|
if (--s->irq.Config == 0) {
|
||||||
@ -437,8 +383,8 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
s->irq.AssignedIRQ = 0;
|
s->irq.AssignedIRQ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->Attributes & IRQ_HANDLE_PRESENT) {
|
if (req->Handler) {
|
||||||
free_irq(req->AssignedIRQ, req->Instance);
|
free_irq(req->AssignedIRQ, p_dev->priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_PROBE
|
#ifdef CONFIG_PCMCIA_PROBE
|
||||||
@ -449,30 +395,34 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
} /* pcmcia_release_irq */
|
} /* pcmcia_release_irq */
|
||||||
|
|
||||||
|
|
||||||
int pcmcia_release_window(window_handle_t win)
|
int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
|
||||||
{
|
{
|
||||||
struct pcmcia_socket *s;
|
struct pcmcia_socket *s = p_dev->socket;
|
||||||
|
pccard_mem_map *win;
|
||||||
|
|
||||||
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
|
wh--;
|
||||||
|
if (wh >= MAX_WIN)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
s = win->sock;
|
|
||||||
if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
|
win = &s->win[wh];
|
||||||
|
|
||||||
|
if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
|
||||||
|
dev_dbg(&s->dev, "not releasing unknown window\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Shut down memory window */
|
/* Shut down memory window */
|
||||||
win->ctl.flags &= ~MAP_ACTIVE;
|
win->flags &= ~MAP_ACTIVE;
|
||||||
s->ops->set_mem_map(s, &win->ctl);
|
s->ops->set_mem_map(s, win);
|
||||||
s->state &= ~SOCKET_WIN_REQ(win->index);
|
s->state &= ~SOCKET_WIN_REQ(wh);
|
||||||
|
|
||||||
/* Release system memory */
|
/* Release system memory */
|
||||||
if (win->ctl.res) {
|
if (win->res) {
|
||||||
release_resource(win->ctl.res);
|
release_resource(win->res);
|
||||||
kfree(win->ctl.res);
|
kfree(win->res);
|
||||||
win->ctl.res = NULL;
|
win->res = NULL;
|
||||||
}
|
}
|
||||||
win->handle->_win &= ~CLIENT_WIN_REQ(win->index);
|
p_dev->_win &= ~CLIENT_WIN_REQ(wh);
|
||||||
|
|
||||||
win->magic = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* pcmcia_release_window */
|
} /* pcmcia_release_window */
|
||||||
@ -492,12 +442,14 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (req->IntType & INT_CARDBUS) {
|
if (req->IntType & INT_CARDBUS) {
|
||||||
ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
|
dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
c = p_dev->function_config;
|
c = p_dev->function_config;
|
||||||
if (c->state & CONFIG_LOCKED)
|
if (c->state & CONFIG_LOCKED) {
|
||||||
|
dev_dbg(&s->dev, "Configuration is locked\n");
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
/* Do power control. We don't allow changes in Vcc. */
|
/* Do power control. We don't allow changes in Vcc. */
|
||||||
s->socket.Vpp = req->Vpp;
|
s->socket.Vpp = req->Vpp;
|
||||||
@ -609,40 +561,44 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
|
|||||||
struct pcmcia_socket *s = p_dev->socket;
|
struct pcmcia_socket *s = p_dev->socket;
|
||||||
config_t *c;
|
config_t *c;
|
||||||
|
|
||||||
if (!(s->state & SOCKET_PRESENT))
|
if (!(s->state & SOCKET_PRESENT)) {
|
||||||
|
dev_dbg(&s->dev, "No card present\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
if (!req)
|
if (!req)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
c = p_dev->function_config;
|
c = p_dev->function_config;
|
||||||
if (c->state & CONFIG_LOCKED)
|
if (c->state & CONFIG_LOCKED) {
|
||||||
|
dev_dbg(&s->dev, "Configuration is locked\n");
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
}
|
||||||
if (c->state & CONFIG_IO_REQ) {
|
if (c->state & CONFIG_IO_REQ) {
|
||||||
ds_dbg(s, 0, "IO already configured\n");
|
dev_dbg(&s->dev, "IO already configured\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
|
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
|
||||||
ds_dbg(s, 0, "bad attribute setting for IO region 1\n");
|
dev_dbg(&s->dev, "bad attribute setting for IO region 1\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if ((req->NumPorts2 > 0) &&
|
if ((req->NumPorts2 > 0) &&
|
||||||
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
|
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
|
||||||
ds_dbg(s, 0, "bad attribute setting for IO region 2\n");
|
dev_dbg(&s->dev, "bad attribute setting for IO region 2\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_dbg(s, 1, "trying to allocate resource 1\n");
|
dev_dbg(&s->dev, "trying to allocate resource 1\n");
|
||||||
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
|
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
|
||||||
req->NumPorts1, req->IOAddrLines)) {
|
req->NumPorts1, req->IOAddrLines)) {
|
||||||
ds_dbg(s, 0, "allocation of resource 1 failed\n");
|
dev_dbg(&s->dev, "allocation of resource 1 failed\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->NumPorts2) {
|
if (req->NumPorts2) {
|
||||||
ds_dbg(s, 1, "trying to allocate resource 2\n");
|
dev_dbg(&s->dev, "trying to allocate resource 2\n");
|
||||||
if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
|
if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
|
||||||
req->NumPorts2, req->IOAddrLines)) {
|
req->NumPorts2, req->IOAddrLines)) {
|
||||||
ds_dbg(s, 0, "allocation of resource 2 failed\n");
|
dev_dbg(&s->dev, "allocation of resource 2 failed\n");
|
||||||
release_io_space(s, req->BasePort1, req->NumPorts1);
|
release_io_space(s, req->BasePort1, req->NumPorts1);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
@ -680,13 +636,17 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
int ret = -EINVAL, irq = 0;
|
int ret = -EINVAL, irq = 0;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
if (!(s->state & SOCKET_PRESENT))
|
if (!(s->state & SOCKET_PRESENT)) {
|
||||||
|
dev_dbg(&s->dev, "No card present\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
c = p_dev->function_config;
|
c = p_dev->function_config;
|
||||||
if (c->state & CONFIG_LOCKED)
|
if (c->state & CONFIG_LOCKED) {
|
||||||
|
dev_dbg(&s->dev, "Configuration is locked\n");
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
}
|
||||||
if (c->state & CONFIG_IRQ_REQ) {
|
if (c->state & CONFIG_IRQ_REQ) {
|
||||||
ds_dbg(s, 0, "IRQ already configured\n");
|
dev_dbg(&s->dev, "IRQ already configured\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,7 +664,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
/* if the underlying IRQ infrastructure allows for it, only allocate
|
/* if the underlying IRQ infrastructure allows for it, only allocate
|
||||||
* the IRQ, but do not enable it
|
* the IRQ, but do not enable it
|
||||||
*/
|
*/
|
||||||
if (!(req->Attributes & IRQ_HANDLE_PRESENT))
|
if (!(req->Handler))
|
||||||
type |= IRQ_NOAUTOEN;
|
type |= IRQ_NOAUTOEN;
|
||||||
#endif /* IRQ_NOAUTOEN */
|
#endif /* IRQ_NOAUTOEN */
|
||||||
|
|
||||||
@ -714,7 +674,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
} else {
|
} else {
|
||||||
int try;
|
int try;
|
||||||
u32 mask = s->irq_mask;
|
u32 mask = s->irq_mask;
|
||||||
void *data = &p_dev->dev.driver; /* something unique to this device */
|
void *data = p_dev; /* something unique to this device */
|
||||||
|
|
||||||
for (try = 0; try < 64; try++) {
|
for (try = 0; try < 64; try++) {
|
||||||
irq = try % 32;
|
irq = try % 32;
|
||||||
@ -731,12 +691,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
* registering a dummy handle works, i.e. if the IRQ isn't
|
* registering a dummy handle works, i.e. if the IRQ isn't
|
||||||
* marked as used by the kernel resource management core */
|
* marked as used by the kernel resource management core */
|
||||||
ret = request_irq(irq,
|
ret = request_irq(irq,
|
||||||
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
|
(req->Handler) ? req->Handler : test_action,
|
||||||
type,
|
type,
|
||||||
p_dev->devname,
|
p_dev->devname,
|
||||||
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
|
(req->Handler) ? p_dev->priv : data);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (!(req->Attributes & IRQ_HANDLE_PRESENT))
|
if (!req->Handler)
|
||||||
free_irq(irq, data);
|
free_irq(irq, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -745,17 +705,22 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||||||
#endif
|
#endif
|
||||||
/* only assign PCI irq if no IRQ already assigned */
|
/* only assign PCI irq if no IRQ already assigned */
|
||||||
if (ret && !s->irq.AssignedIRQ) {
|
if (ret && !s->irq.AssignedIRQ) {
|
||||||
if (!s->pci_irq)
|
if (!s->pci_irq) {
|
||||||
|
dev_printk(KERN_INFO, &s->dev, "no IRQ found\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
type = IRQF_SHARED;
|
type = IRQF_SHARED;
|
||||||
irq = s->pci_irq;
|
irq = s->pci_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
|
if (ret && req->Handler) {
|
||||||
ret = request_irq(irq, req->Handler, type,
|
ret = request_irq(irq, req->Handler, type,
|
||||||
p_dev->devname, req->Instance);
|
p_dev->devname, p_dev->priv);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
dev_printk(KERN_INFO, &s->dev,
|
||||||
|
"request_irq() failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the fact the request type was overridden is passed back */
|
/* Make sure the fact the request type was overridden is passed back */
|
||||||
@ -787,17 +752,19 @@ EXPORT_SYMBOL(pcmcia_request_irq);
|
|||||||
* Request_window() establishes a mapping between card memory space
|
* Request_window() establishes a mapping between card memory space
|
||||||
* and system memory space.
|
* and system memory space.
|
||||||
*/
|
*/
|
||||||
int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
|
int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh)
|
||||||
{
|
{
|
||||||
struct pcmcia_socket *s = (*p_dev)->socket;
|
struct pcmcia_socket *s = p_dev->socket;
|
||||||
window_t *win;
|
pccard_mem_map *win;
|
||||||
u_long align;
|
u_long align;
|
||||||
int w;
|
int w;
|
||||||
|
|
||||||
if (!(s->state & SOCKET_PRESENT))
|
if (!(s->state & SOCKET_PRESENT)) {
|
||||||
|
dev_dbg(&s->dev, "No card present\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
|
if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
|
||||||
ds_dbg(s, 0, "bad attribute setting for iomem region\n");
|
dev_dbg(&s->dev, "bad attribute setting for iomem region\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,12 +775,12 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
|
|||||||
(req->Attributes & WIN_STRICT_ALIGN)) ?
|
(req->Attributes & WIN_STRICT_ALIGN)) ?
|
||||||
req->Size : s->map_size);
|
req->Size : s->map_size);
|
||||||
if (req->Size & (s->map_size-1)) {
|
if (req->Size & (s->map_size-1)) {
|
||||||
ds_dbg(s, 0, "invalid map size\n");
|
dev_dbg(&s->dev, "invalid map size\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
|
if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
|
||||||
(req->Base & (align-1))) {
|
(req->Base & (align-1))) {
|
||||||
ds_dbg(s, 0, "invalid base address\n");
|
dev_dbg(&s->dev, "invalid base address\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (req->Base)
|
if (req->Base)
|
||||||
@ -823,52 +790,48 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
|
|||||||
for (w = 0; w < MAX_WIN; w++)
|
for (w = 0; w < MAX_WIN; w++)
|
||||||
if (!(s->state & SOCKET_WIN_REQ(w))) break;
|
if (!(s->state & SOCKET_WIN_REQ(w))) break;
|
||||||
if (w == MAX_WIN) {
|
if (w == MAX_WIN) {
|
||||||
ds_dbg(s, 0, "all windows are used already\n");
|
dev_dbg(&s->dev, "all windows are used already\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
win = &s->win[w];
|
win = &s->win[w];
|
||||||
win->magic = WINDOW_MAGIC;
|
|
||||||
win->index = w;
|
|
||||||
win->handle = *p_dev;
|
|
||||||
win->sock = s;
|
|
||||||
|
|
||||||
if (!(s->features & SS_CAP_STATIC_MAP)) {
|
if (!(s->features & SS_CAP_STATIC_MAP)) {
|
||||||
win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
|
win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
|
||||||
(req->Attributes & WIN_MAP_BELOW_1MB), s);
|
(req->Attributes & WIN_MAP_BELOW_1MB), s);
|
||||||
if (!win->ctl.res) {
|
if (!win->res) {
|
||||||
ds_dbg(s, 0, "allocating mem region failed\n");
|
dev_dbg(&s->dev, "allocating mem region failed\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*p_dev)->_win |= CLIENT_WIN_REQ(w);
|
p_dev->_win |= CLIENT_WIN_REQ(w);
|
||||||
|
|
||||||
/* Configure the socket controller */
|
/* Configure the socket controller */
|
||||||
win->ctl.map = w+1;
|
win->map = w+1;
|
||||||
win->ctl.flags = 0;
|
win->flags = 0;
|
||||||
win->ctl.speed = req->AccessSpeed;
|
win->speed = req->AccessSpeed;
|
||||||
if (req->Attributes & WIN_MEMORY_TYPE)
|
if (req->Attributes & WIN_MEMORY_TYPE)
|
||||||
win->ctl.flags |= MAP_ATTRIB;
|
win->flags |= MAP_ATTRIB;
|
||||||
if (req->Attributes & WIN_ENABLE)
|
if (req->Attributes & WIN_ENABLE)
|
||||||
win->ctl.flags |= MAP_ACTIVE;
|
win->flags |= MAP_ACTIVE;
|
||||||
if (req->Attributes & WIN_DATA_WIDTH_16)
|
if (req->Attributes & WIN_DATA_WIDTH_16)
|
||||||
win->ctl.flags |= MAP_16BIT;
|
win->flags |= MAP_16BIT;
|
||||||
if (req->Attributes & WIN_USE_WAIT)
|
if (req->Attributes & WIN_USE_WAIT)
|
||||||
win->ctl.flags |= MAP_USE_WAIT;
|
win->flags |= MAP_USE_WAIT;
|
||||||
win->ctl.card_start = 0;
|
win->card_start = 0;
|
||||||
if (s->ops->set_mem_map(s, &win->ctl) != 0) {
|
if (s->ops->set_mem_map(s, win) != 0) {
|
||||||
ds_dbg(s, 0, "failed to set memory mapping\n");
|
dev_dbg(&s->dev, "failed to set memory mapping\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
s->state |= SOCKET_WIN_REQ(w);
|
s->state |= SOCKET_WIN_REQ(w);
|
||||||
|
|
||||||
/* Return window handle */
|
/* Return window handle */
|
||||||
if (s->features & SS_CAP_STATIC_MAP) {
|
if (s->features & SS_CAP_STATIC_MAP) {
|
||||||
req->Base = win->ctl.static_start;
|
req->Base = win->static_start;
|
||||||
} else {
|
} else {
|
||||||
req->Base = win->ctl.res->start;
|
req->Base = win->res->start;
|
||||||
}
|
}
|
||||||
*wh = win;
|
*wh = w + 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* pcmcia_request_window */
|
} /* pcmcia_request_window */
|
||||||
@ -879,18 +842,45 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
|
|||||||
pcmcia_release_io(p_dev, &p_dev->io);
|
pcmcia_release_io(p_dev, &p_dev->io);
|
||||||
pcmcia_release_irq(p_dev, &p_dev->irq);
|
pcmcia_release_irq(p_dev, &p_dev->irq);
|
||||||
if (p_dev->win)
|
if (p_dev->win)
|
||||||
pcmcia_release_window(p_dev->win);
|
pcmcia_release_window(p_dev, p_dev->win);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pcmcia_disable_device);
|
EXPORT_SYMBOL(pcmcia_disable_device);
|
||||||
|
|
||||||
|
|
||||||
struct pcmcia_cfg_mem {
|
struct pcmcia_cfg_mem {
|
||||||
tuple_t tuple;
|
struct pcmcia_device *p_dev;
|
||||||
|
void *priv_data;
|
||||||
|
int (*conf_check) (struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data);
|
||||||
cisparse_t parse;
|
cisparse_t parse;
|
||||||
u8 buf[256];
|
|
||||||
cistpl_cftable_entry_t dflt;
|
cistpl_cftable_entry_t dflt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
|
||||||
|
*
|
||||||
|
* pcmcia_do_loop_config() is the internal callback for the call from
|
||||||
|
* pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
|
||||||
|
* by a struct pcmcia_cfg_mem.
|
||||||
|
*/
|
||||||
|
static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
|
||||||
|
{
|
||||||
|
cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
|
||||||
|
struct pcmcia_cfg_mem *cfg_mem = priv;
|
||||||
|
|
||||||
|
/* default values */
|
||||||
|
cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
|
||||||
|
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||||
|
cfg_mem->dflt = *cfg;
|
||||||
|
|
||||||
|
return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
|
||||||
|
cfg_mem->p_dev->socket->socket.Vcc,
|
||||||
|
cfg_mem->priv_data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pcmcia_loop_config() - loop over configuration options
|
* pcmcia_loop_config() - loop over configuration options
|
||||||
* @p_dev: the struct pcmcia_device which we need to loop for.
|
* @p_dev: the struct pcmcia_device which we need to loop for.
|
||||||
@ -913,48 +903,174 @@ int pcmcia_loop_config(struct pcmcia_device *p_dev,
|
|||||||
void *priv_data)
|
void *priv_data)
|
||||||
{
|
{
|
||||||
struct pcmcia_cfg_mem *cfg_mem;
|
struct pcmcia_cfg_mem *cfg_mem;
|
||||||
|
|
||||||
tuple_t *tuple;
|
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int vcc;
|
|
||||||
|
|
||||||
cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
|
cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
|
||||||
if (cfg_mem == NULL)
|
if (cfg_mem == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* get the current Vcc setting */
|
cfg_mem->p_dev = p_dev;
|
||||||
vcc = p_dev->socket->socket.Vcc;
|
cfg_mem->conf_check = conf_check;
|
||||||
|
cfg_mem->priv_data = priv_data;
|
||||||
|
|
||||||
tuple = &cfg_mem->tuple;
|
ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
|
||||||
tuple->TupleData = cfg_mem->buf;
|
CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
|
||||||
tuple->TupleDataMax = 255;
|
cfg_mem, pcmcia_do_loop_config);
|
||||||
tuple->TupleOffset = 0;
|
|
||||||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
tuple->Attributes = 0;
|
|
||||||
|
|
||||||
ret = pcmcia_get_first_tuple(p_dev, tuple);
|
|
||||||
while (!ret) {
|
|
||||||
cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
|
|
||||||
|
|
||||||
if (pcmcia_get_tuple_data(p_dev, tuple))
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
if (pcmcia_parse_tuple(tuple, &cfg_mem->parse))
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
/* default values */
|
|
||||||
p_dev->conf.ConfigIndex = cfg->index;
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
|
||||||
cfg_mem->dflt = *cfg;
|
|
||||||
|
|
||||||
ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
|
|
||||||
if (!ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
next_entry:
|
|
||||||
ret = pcmcia_get_next_tuple(p_dev, tuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
kfree(cfg_mem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pcmcia_loop_config);
|
EXPORT_SYMBOL(pcmcia_loop_config);
|
||||||
|
|
||||||
|
|
||||||
|
struct pcmcia_loop_mem {
|
||||||
|
struct pcmcia_device *p_dev;
|
||||||
|
void *priv_data;
|
||||||
|
int (*loop_tuple) (struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv_data);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
|
||||||
|
*
|
||||||
|
* pcmcia_do_loop_tuple() is the internal callback for the call from
|
||||||
|
* pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
|
||||||
|
* by a struct pcmcia_cfg_mem.
|
||||||
|
*/
|
||||||
|
static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
|
||||||
|
{
|
||||||
|
struct pcmcia_loop_mem *loop = priv;
|
||||||
|
|
||||||
|
return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_loop_tuple() - loop over tuples in the CIS
|
||||||
|
* @p_dev: the struct pcmcia_device which we need to loop for.
|
||||||
|
* @code: which CIS code shall we look for?
|
||||||
|
* @priv_data: private data to be passed to the loop_tuple function.
|
||||||
|
* @loop_tuple: function to call for each CIS entry of type @function. IT
|
||||||
|
* gets passed the raw tuple and @priv_data.
|
||||||
|
*
|
||||||
|
* pcmcia_loop_tuple() loops over all CIS entries of type @function, and
|
||||||
|
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
|
||||||
|
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
|
||||||
|
*/
|
||||||
|
int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
|
||||||
|
int (*loop_tuple) (struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv_data),
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
struct pcmcia_loop_mem loop = {
|
||||||
|
.p_dev = p_dev,
|
||||||
|
.loop_tuple = loop_tuple,
|
||||||
|
.priv_data = priv_data};
|
||||||
|
|
||||||
|
return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
|
||||||
|
&loop, pcmcia_do_loop_tuple);
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL(pcmcia_loop_tuple);
|
||||||
|
|
||||||
|
|
||||||
|
struct pcmcia_loop_get {
|
||||||
|
size_t len;
|
||||||
|
cisdata_t **buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
|
||||||
|
*
|
||||||
|
* pcmcia_do_get_tuple() is the internal callback for the call from
|
||||||
|
* pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
|
||||||
|
* the first tuple, return 0 unconditionally. Create a memory buffer large
|
||||||
|
* enough to hold the content of the tuple, and fill it with the tuple data.
|
||||||
|
* The caller is responsible to free the buffer.
|
||||||
|
*/
|
||||||
|
static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
struct pcmcia_loop_get *get = priv;
|
||||||
|
|
||||||
|
*get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
|
||||||
|
if (*get->buf) {
|
||||||
|
get->len = tuple->TupleDataLen;
|
||||||
|
memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
|
||||||
|
} else
|
||||||
|
dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_get_tuple() - get first tuple from CIS
|
||||||
|
* @p_dev: the struct pcmcia_device which we need to loop for.
|
||||||
|
* @code: which CIS code shall we look for?
|
||||||
|
* @buf: pointer to store the buffer to.
|
||||||
|
*
|
||||||
|
* pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
|
||||||
|
* It returns the buffer length (or zero). The caller is responsible to free
|
||||||
|
* the buffer passed in @buf.
|
||||||
|
*/
|
||||||
|
size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
|
||||||
|
unsigned char **buf)
|
||||||
|
{
|
||||||
|
struct pcmcia_loop_get get = {
|
||||||
|
.len = 0,
|
||||||
|
.buf = buf,
|
||||||
|
};
|
||||||
|
|
||||||
|
*get.buf = NULL;
|
||||||
|
pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
|
||||||
|
|
||||||
|
return get.len;
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL(pcmcia_get_tuple);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
|
||||||
|
*
|
||||||
|
* pcmcia_do_get_mac() is the internal callback for the call from
|
||||||
|
* pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
|
||||||
|
* tuple contains a proper LAN_NODE_ID of length 6, and copy the data
|
||||||
|
* to struct net_device->dev_addr[i].
|
||||||
|
*/
|
||||||
|
static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
struct net_device *dev = priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
|
||||||
|
return -EINVAL;
|
||||||
|
if (tuple->TupleDataLen < ETH_ALEN + 2) {
|
||||||
|
dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
|
||||||
|
"LAN_NODE_ID\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tuple->TupleData[1] != ETH_ALEN) {
|
||||||
|
dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
dev->dev_addr[i] = tuple->TupleData[i+2];
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
|
||||||
|
* @p_dev: the struct pcmcia_device for which we want the address.
|
||||||
|
* @dev: a properly prepared struct net_device to store the info to.
|
||||||
|
*
|
||||||
|
* pcmcia_get_mac_from_cis() reads out the hardware MAC address from
|
||||||
|
* CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
|
||||||
|
* must be set up properly by the driver (see examples!).
|
||||||
|
*/
|
||||||
|
int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
|
||||||
|
{
|
||||||
|
return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
|
||||||
|
|
||||||
|
@ -213,7 +213,8 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev)
|
|||||||
|
|
||||||
if (csc & I365_CSC_DETECT) {
|
if (csc & I365_CSC_DETECT) {
|
||||||
events |= SS_DETECT;
|
events |= SS_DETECT;
|
||||||
dprintk("Card detected in socket %i!\n", i);
|
dev_vdbg(&socket[i].socket.dev,
|
||||||
|
"Card detected in socket %i!\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indirect_read(&socket[i], I365_INTCTL)
|
if (indirect_read(&socket[i], I365_INTCTL)
|
||||||
@ -331,11 +332,11 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
|
|||||||
reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
|
reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
|
||||||
|
|
||||||
if (state->flags & SS_PWR_AUTO) {
|
if (state->flags & SS_PWR_AUTO) {
|
||||||
dprintk("Auto power\n");
|
dev_dbg(&sock->dev, "Auto power\n");
|
||||||
reg |= I365_PWR_AUTO; /* automatic power mngmnt */
|
reg |= I365_PWR_AUTO; /* automatic power mngmnt */
|
||||||
}
|
}
|
||||||
if (state->flags & SS_OUTPUT_ENA) {
|
if (state->flags & SS_OUTPUT_ENA) {
|
||||||
dprintk("Power Enabled\n");
|
dev_dbg(&sock->dev, "Power Enabled\n");
|
||||||
reg |= I365_PWR_OUT; /* enable power */
|
reg |= I365_PWR_OUT; /* enable power */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,40 +344,44 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 33:
|
case 33:
|
||||||
dprintk("setting voltage to Vcc to 3.3V on socket %i\n",
|
dev_dbg(&sock->dev,
|
||||||
|
"setting voltage to Vcc to 3.3V on socket %i\n",
|
||||||
socket->number);
|
socket->number);
|
||||||
reg |= I365_VCC_5V;
|
reg |= I365_VCC_5V;
|
||||||
indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
|
indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
|
||||||
break;
|
break;
|
||||||
case 50:
|
case 50:
|
||||||
dprintk("setting voltage to Vcc to 5V on socket %i\n",
|
dev_dbg(&sock->dev,
|
||||||
|
"setting voltage to Vcc to 5V on socket %i\n",
|
||||||
socket->number);
|
socket->number);
|
||||||
reg |= I365_VCC_5V;
|
reg |= I365_VCC_5V;
|
||||||
indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
|
indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dprintk("pd6729: pd6729_set_socket called with "
|
dev_dbg(&sock->dev,
|
||||||
"invalid VCC power value: %i\n",
|
"pd6729_set_socket called with invalid VCC power "
|
||||||
state->Vcc);
|
"value: %i\n", state->Vcc);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state->Vpp) {
|
switch (state->Vpp) {
|
||||||
case 0:
|
case 0:
|
||||||
dprintk("not setting Vpp on socket %i\n", socket->number);
|
dev_dbg(&sock->dev, "not setting Vpp on socket %i\n",
|
||||||
|
socket->number);
|
||||||
break;
|
break;
|
||||||
case 33:
|
case 33:
|
||||||
case 50:
|
case 50:
|
||||||
dprintk("setting Vpp to Vcc for socket %i\n", socket->number);
|
dev_dbg(&sock->dev, "setting Vpp to Vcc for socket %i\n",
|
||||||
|
socket->number);
|
||||||
reg |= I365_VPP1_5V;
|
reg |= I365_VPP1_5V;
|
||||||
break;
|
break;
|
||||||
case 120:
|
case 120:
|
||||||
dprintk("setting Vpp to 12.0\n");
|
dev_dbg(&sock->dev, "setting Vpp to 12.0\n");
|
||||||
reg |= I365_VPP1_12V;
|
reg |= I365_VPP1_12V;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i\n",
|
dev_dbg(&sock->dev, "pd6729: pd6729_set_socket called with "
|
||||||
state->Vpp);
|
"invalid VPP power value: %i\n", state->Vpp);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,7 +443,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
|
|||||||
|
|
||||||
/* Check error conditions */
|
/* Check error conditions */
|
||||||
if (map > 1) {
|
if (map > 1) {
|
||||||
dprintk("pd6729_set_io_map with invalid map");
|
dev_dbg(&sock->dev, "pd6729_set_io_map with invalid map\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +451,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
|
|||||||
if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map))
|
if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map))
|
||||||
indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map));
|
indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map));
|
||||||
|
|
||||||
/* dprintk("set_io_map: Setting range to %x - %x\n",
|
/* dev_dbg(&sock->dev, "set_io_map: Setting range to %x - %x\n",
|
||||||
io->start, io->stop);*/
|
io->start, io->stop);*/
|
||||||
|
|
||||||
/* write the new values */
|
/* write the new values */
|
||||||
@ -478,12 +483,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
|
|||||||
|
|
||||||
map = mem->map;
|
map = mem->map;
|
||||||
if (map > 4) {
|
if (map > 4) {
|
||||||
printk("pd6729_set_mem_map: invalid map");
|
dev_warn(&sock->dev, "invalid map requested\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mem->res->start > mem->res->end) || (mem->speed > 1000)) {
|
if ((mem->res->start > mem->res->end) || (mem->speed > 1000)) {
|
||||||
printk("pd6729_set_mem_map: invalid address / speed");
|
dev_warn(&sock->dev, "invalid invalid address / speed\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,12 +534,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
|
|||||||
if (mem->flags & MAP_WRPROT)
|
if (mem->flags & MAP_WRPROT)
|
||||||
i |= I365_MEM_WRPROT;
|
i |= I365_MEM_WRPROT;
|
||||||
if (mem->flags & MAP_ATTRIB) {
|
if (mem->flags & MAP_ATTRIB) {
|
||||||
/* dprintk("requesting attribute memory for socket %i\n",
|
/* dev_dbg(&sock->dev, "requesting attribute memory for "
|
||||||
socket->number);*/
|
"socket %i\n", socket->number);*/
|
||||||
i |= I365_MEM_REG;
|
i |= I365_MEM_REG;
|
||||||
} else {
|
} else {
|
||||||
/* dprintk("requesting normal memory for socket %i\n",
|
/* dev_dbg(&sock->dev, "requesting normal memory for "
|
||||||
socket->number);*/
|
"socket %i\n", socket->number);*/
|
||||||
}
|
}
|
||||||
indirect_write16(socket, base + I365_W_OFF, i);
|
indirect_write16(socket, base + I365_W_OFF, i);
|
||||||
|
|
||||||
@ -577,7 +582,7 @@ static struct pccard_operations pd6729_operations = {
|
|||||||
|
|
||||||
static irqreturn_t pd6729_test(int irq, void *dev)
|
static irqreturn_t pd6729_test(int irq, void *dev)
|
||||||
{
|
{
|
||||||
dprintk("-> hit on irq %d\n", irq);
|
pr_devel("-> hit on irq %d\n", irq);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,13 +647,13 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
|
|||||||
goto err_out_free_mem;
|
goto err_out_free_mem;
|
||||||
|
|
||||||
if (!pci_resource_start(dev, 0)) {
|
if (!pci_resource_start(dev, 0)) {
|
||||||
printk(KERN_INFO "pd6729: refusing to load the driver "
|
dev_warn(&dev->dev, "refusing to load the driver as the "
|
||||||
"as the io_base is 0.\n");
|
"io_base is NULL.\n");
|
||||||
goto err_out_free_mem;
|
goto err_out_free_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge "
|
dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
|
||||||
"at 0x%llx on irq %d\n",
|
"on irq %d\n",
|
||||||
(unsigned long long)pci_resource_start(dev, 0), dev->irq);
|
(unsigned long long)pci_resource_start(dev, 0), dev->irq);
|
||||||
/*
|
/*
|
||||||
* Since we have no memory BARs some firmware may not
|
* Since we have no memory BARs some firmware may not
|
||||||
@ -656,14 +661,14 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
|
|||||||
*/
|
*/
|
||||||
pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
|
pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
|
||||||
if (!(configbyte & PCI_COMMAND_MEMORY)) {
|
if (!(configbyte & PCI_COMMAND_MEMORY)) {
|
||||||
printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
|
dev_dbg(&dev->dev, "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
|
||||||
configbyte |= PCI_COMMAND_MEMORY;
|
configbyte |= PCI_COMMAND_MEMORY;
|
||||||
pci_write_config_byte(dev, PCI_COMMAND, configbyte);
|
pci_write_config_byte(dev, PCI_COMMAND, configbyte);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pci_request_regions(dev, "pd6729");
|
ret = pci_request_regions(dev, "pd6729");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_INFO "pd6729: pci request region failed.\n");
|
dev_warn(&dev->dev, "pci request region failed.\n");
|
||||||
goto err_out_disable;
|
goto err_out_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +677,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
|
|||||||
|
|
||||||
mask = pd6729_isa_scan();
|
mask = pd6729_isa_scan();
|
||||||
if (irq_mode == 0 && mask == 0) {
|
if (irq_mode == 0 && mask == 0) {
|
||||||
printk(KERN_INFO "pd6729: no ISA interrupt is available.\n");
|
dev_warn(&dev->dev, "no ISA interrupt is available.\n");
|
||||||
goto err_out_free_res;
|
goto err_out_free_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,8 +702,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
|
|||||||
/* Register the interrupt handler */
|
/* Register the interrupt handler */
|
||||||
if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
|
if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
|
||||||
"pd6729", socket))) {
|
"pd6729", socket))) {
|
||||||
printk(KERN_ERR "pd6729: Failed to register irq %d, "
|
dev_err(&dev->dev, "Failed to register irq %d\n",
|
||||||
"aborting\n", dev->irq);
|
dev->irq);
|
||||||
goto err_out_free_res;
|
goto err_out_free_res;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -713,8 +718,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
|
|||||||
for (i = 0; i < MAX_SOCKETS; i++) {
|
for (i = 0; i < MAX_SOCKETS; i++) {
|
||||||
ret = pcmcia_register_socket(&socket[i].socket);
|
ret = pcmcia_register_socket(&socket[i].socket);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_INFO "pd6729: pcmcia_register_socket "
|
dev_warn(&dev->dev, "pcmcia_register_socket failed.\n");
|
||||||
"failed.\n");
|
|
||||||
for (j = 0; j < i ; j++)
|
for (j = 0; j < i ; j++)
|
||||||
pcmcia_unregister_socket(&socket[j].socket);
|
pcmcia_unregister_socket(&socket[j].socket);
|
||||||
goto err_out_free_res2;
|
goto err_out_free_res2;
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
#ifndef _INCLUDE_GUARD_PD6729_H_
|
#ifndef _INCLUDE_GUARD_PD6729_H_
|
||||||
#define _INCLUDE_GUARD_PD6729_H_
|
#define _INCLUDE_GUARD_PD6729_H_
|
||||||
|
|
||||||
/* Debuging defines */
|
|
||||||
#ifdef NOTRACE
|
|
||||||
#define dprintk(fmt, args...) printk(fmt , ## args)
|
|
||||||
#else
|
|
||||||
#define dprintk(fmt, args...) do {} while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Flags for I365_GENCTL */
|
/* Flags for I365_GENCTL */
|
||||||
#define I365_DF_VS1 0x40 /* DF-step Voltage Sense */
|
#define I365_DF_VS1 0x40 /* DF-step Voltage Sense */
|
||||||
#define I365_DF_VS2 0x80
|
#define I365_DF_VS2 0x80
|
||||||
|
@ -228,9 +228,43 @@ static const char *skt_names[] = {
|
|||||||
#define SKT_DEV_INFO_SIZE(n) \
|
#define SKT_DEV_INFO_SIZE(n) \
|
||||||
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
|
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
|
||||||
|
|
||||||
|
int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
|
||||||
|
{
|
||||||
|
skt->res_skt.start = _PCMCIA(skt->nr);
|
||||||
|
skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
|
||||||
|
skt->res_skt.name = skt_names[skt->nr];
|
||||||
|
skt->res_skt.flags = IORESOURCE_MEM;
|
||||||
|
|
||||||
|
skt->res_io.start = _PCMCIAIO(skt->nr);
|
||||||
|
skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
|
||||||
|
skt->res_io.name = "io";
|
||||||
|
skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
||||||
|
|
||||||
|
skt->res_mem.start = _PCMCIAMem(skt->nr);
|
||||||
|
skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
|
||||||
|
skt->res_mem.name = "memory";
|
||||||
|
skt->res_mem.flags = IORESOURCE_MEM;
|
||||||
|
|
||||||
|
skt->res_attr.start = _PCMCIAAttr(skt->nr);
|
||||||
|
skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
|
||||||
|
skt->res_attr.name = "attribute";
|
||||||
|
skt->res_attr.flags = IORESOURCE_MEM;
|
||||||
|
|
||||||
|
return soc_pcmcia_add_one(skt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
|
||||||
|
{
|
||||||
|
/* Provide our PXA2xx specific timing routines. */
|
||||||
|
ops->set_timing = pxa2xx_pcmcia_set_timing;
|
||||||
|
#ifdef CONFIG_CPU_FREQ
|
||||||
|
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret = 0;
|
||||||
struct pcmcia_low_level *ops;
|
struct pcmcia_low_level *ops;
|
||||||
struct skt_dev_info *sinfo;
|
struct skt_dev_info *sinfo;
|
||||||
struct soc_pcmcia_socket *skt;
|
struct soc_pcmcia_socket *skt;
|
||||||
@ -240,6 +274,8 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
|||||||
|
|
||||||
ops = (struct pcmcia_low_level *)dev->platform_data;
|
ops = (struct pcmcia_low_level *)dev->platform_data;
|
||||||
|
|
||||||
|
pxa2xx_drv_pcmcia_ops(ops);
|
||||||
|
|
||||||
sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
|
sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
|
||||||
if (!sinfo)
|
if (!sinfo)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -250,40 +286,25 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
|||||||
for (i = 0; i < ops->nr; i++) {
|
for (i = 0; i < ops->nr; i++) {
|
||||||
skt = &sinfo->skt[i];
|
skt = &sinfo->skt[i];
|
||||||
|
|
||||||
skt->nr = ops->first + i;
|
skt->nr = ops->first + i;
|
||||||
skt->irq = NO_IRQ;
|
skt->ops = ops;
|
||||||
|
skt->socket.owner = ops->owner;
|
||||||
|
skt->socket.dev.parent = dev;
|
||||||
|
skt->socket.pci_irq = NO_IRQ;
|
||||||
|
|
||||||
skt->res_skt.start = _PCMCIA(skt->nr);
|
ret = pxa2xx_drv_pcmcia_add_one(skt);
|
||||||
skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
|
if (ret)
|
||||||
skt->res_skt.name = skt_names[skt->nr];
|
break;
|
||||||
skt->res_skt.flags = IORESOURCE_MEM;
|
|
||||||
|
|
||||||
skt->res_io.start = _PCMCIAIO(skt->nr);
|
|
||||||
skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
|
|
||||||
skt->res_io.name = "io";
|
|
||||||
skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
|
||||||
|
|
||||||
skt->res_mem.start = _PCMCIAMem(skt->nr);
|
|
||||||
skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
|
|
||||||
skt->res_mem.name = "memory";
|
|
||||||
skt->res_mem.flags = IORESOURCE_MEM;
|
|
||||||
|
|
||||||
skt->res_attr.start = _PCMCIAAttr(skt->nr);
|
|
||||||
skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
|
|
||||||
skt->res_attr.name = "attribute";
|
|
||||||
skt->res_attr.flags = IORESOURCE_MEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Provide our PXA2xx specific timing routines. */
|
if (ret) {
|
||||||
ops->set_timing = pxa2xx_pcmcia_set_timing;
|
while (--i >= 0)
|
||||||
#ifdef CONFIG_CPU_FREQ
|
soc_pcmcia_remove_one(&sinfo->skt[i]);
|
||||||
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
|
kfree(sinfo);
|
||||||
#endif
|
} else {
|
||||||
|
|
||||||
ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
pxa2xx_configure_sockets(dev);
|
pxa2xx_configure_sockets(dev);
|
||||||
|
dev_set_drvdata(dev, sinfo);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -297,7 +318,16 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
|
|||||||
|
|
||||||
static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
|
static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
return soc_common_drv_pcmcia_remove(&dev->dev);
|
struct skt_dev_info *sinfo = platform_get_drvdata(dev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
platform_set_drvdata(dev, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < sinfo->nskt; i++)
|
||||||
|
soc_pcmcia_remove_one(&sinfo->skt[i]);
|
||||||
|
|
||||||
|
kfree(sinfo);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
|
static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
/* temporary measure */
|
/* temporary measure */
|
||||||
extern int __pxa2xx_drv_pcmcia_probe(struct device *);
|
extern int __pxa2xx_drv_pcmcia_probe(struct device *);
|
||||||
|
|
||||||
|
int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
|
||||||
|
void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
return ret;
|
return ret;
|
||||||
gpio_direction_output(GPIO_PCMCIA_RESET, 0);
|
gpio_direction_output(GPIO_PCMCIA_RESET, 0);
|
||||||
|
|
||||||
skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
|
skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
|
||||||
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
gpio_free(GPIO_PCMCIA_RESET);
|
gpio_free(GPIO_PCMCIA_RESET);
|
||||||
|
@ -38,7 +38,7 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
return ret;
|
return ret;
|
||||||
gpio_direction_output(GPIO_PCMCIA_RESET, 0);
|
gpio_direction_output(GPIO_PCMCIA_RESET, 0);
|
||||||
|
|
||||||
skt->irq = PCMCIA_S0_RDYINT;
|
skt->socket.pci_irq = PCMCIA_S0_RDYINT;
|
||||||
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
gpio_free(GPIO_PCMCIA_RESET);
|
gpio_free(GPIO_PCMCIA_RESET);
|
||||||
|
@ -38,7 +38,7 @@ static struct pcmcia_irqs cd_irqs[] = {
|
|||||||
|
|
||||||
static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
skt->irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
|
skt->socket.pci_irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
|
||||||
IRQ_GPIO(GPIO_E740_PCMCIA_RDY1);
|
IRQ_GPIO(GPIO_E740_PCMCIA_RDY1);
|
||||||
|
|
||||||
return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1);
|
return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1);
|
||||||
|
@ -32,6 +32,7 @@ static int
|
|||||||
lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
||||||
const socket_state_t *state)
|
const socket_state_t *state)
|
||||||
{
|
{
|
||||||
|
struct sa1111_pcmcia_socket *s = to_skt(skt);
|
||||||
unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
|
unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
|||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
lubbock_set_misc_wr(misc_mask, misc_set);
|
lubbock_set_misc_wr(misc_mask, misc_set);
|
||||||
sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
|
sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@ -175,7 +176,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
|||||||
* Switch to 5V, Configure socket with 5V voltage
|
* Switch to 5V, Configure socket with 5V voltage
|
||||||
*/
|
*/
|
||||||
lubbock_set_misc_wr(misc_mask, 0);
|
lubbock_set_misc_wr(misc_mask, 0);
|
||||||
sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0);
|
sa1111_set_io(s->dev, pa_dwr_mask, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It takes about 100ms to turn off Vcc.
|
* It takes about 100ms to turn off Vcc.
|
||||||
@ -200,12 +201,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
|
|||||||
|
|
||||||
static struct pcmcia_low_level lubbock_pcmcia_ops = {
|
static struct pcmcia_low_level lubbock_pcmcia_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.hw_init = sa1111_pcmcia_hw_init,
|
|
||||||
.hw_shutdown = sa1111_pcmcia_hw_shutdown,
|
|
||||||
.socket_state = sa1111_pcmcia_socket_state,
|
|
||||||
.configure_socket = lubbock_pcmcia_configure_socket,
|
.configure_socket = lubbock_pcmcia_configure_socket,
|
||||||
.socket_init = sa1111_pcmcia_socket_init,
|
.socket_init = sa1111_pcmcia_socket_init,
|
||||||
.socket_suspend = sa1111_pcmcia_socket_suspend,
|
|
||||||
.first = 0,
|
.first = 0,
|
||||||
.nr = 2,
|
.nr = 2,
|
||||||
};
|
};
|
||||||
@ -228,8 +225,9 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
|
|||||||
/* Set CF Socket 1 power to standby mode. */
|
/* Set CF Socket 1 power to standby mode. */
|
||||||
lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
|
lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
|
||||||
|
|
||||||
sadev->dev.platform_data = &lubbock_pcmcia_ops;
|
pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
|
||||||
ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev);
|
ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
|
||||||
|
pxa2xx_drv_pcmcia_add_one);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -44,7 +44,7 @@ static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
* before we enable them as outputs.
|
* before we enable them as outputs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
skt->irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
|
skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err4;
|
goto err4;
|
||||||
|
|
||||||
skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
|
skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err4:
|
err4:
|
||||||
|
@ -53,7 +53,7 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err5;
|
goto err5;
|
||||||
|
|
||||||
skt->irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
|
skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err5:
|
err5:
|
||||||
|
@ -66,7 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skt->irq = SCOOP_DEV[skt->nr].irq;
|
skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
gpio_free(GPIO_PRDY);
|
gpio_free(GPIO_PRDY);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
skt->irq = IRQ_GPIO(GPIO_PRDY);
|
skt->socket.pci_irq = IRQ_GPIO(GPIO_PRDY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef CONFIG_MACH_TRIZEPS_CONXS
|
#ifndef CONFIG_MACH_TRIZEPS_CONXS
|
||||||
@ -63,7 +63,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* release the reset of this card */
|
/* release the reset of this card */
|
||||||
pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
|
pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
|
||||||
|
|
||||||
/* supplementory irqs for the socket */
|
/* supplementory irqs for the socket */
|
||||||
for (i = 0; i < ARRAY_SIZE(irqs); i++) {
|
for (i = 0; i < ARRAY_SIZE(irqs); i++) {
|
||||||
|
@ -40,7 +40,7 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
|
skt->socket.pci_irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
|
||||||
|
|
||||||
if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
|
if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
|
||||||
goto err_request_cd;
|
goto err_request_cd;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/ss.h>
|
#include <pcmcia/ss.h>
|
||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
|
#include <pcmcia/cistpl.h>
|
||||||
#include "cs_internal.h"
|
#include "cs_internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
|
|||||||
|
|
||||||
static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
skt->irq = ASSABET_IRQ_GPIO_CF_IRQ;
|
skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ;
|
||||||
|
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
@ -127,13 +127,10 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
|
|||||||
|
|
||||||
static struct pcmcia_low_level badge4_pcmcia_ops = {
|
static struct pcmcia_low_level badge4_pcmcia_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.hw_init = sa1111_pcmcia_hw_init,
|
|
||||||
.hw_shutdown = sa1111_pcmcia_hw_shutdown,
|
|
||||||
.socket_state = sa1111_pcmcia_socket_state,
|
|
||||||
.configure_socket = badge4_pcmcia_configure_socket,
|
.configure_socket = badge4_pcmcia_configure_socket,
|
||||||
|
|
||||||
.socket_init = sa1111_pcmcia_socket_init,
|
.socket_init = sa1111_pcmcia_socket_init,
|
||||||
.socket_suspend = sa1111_pcmcia_socket_suspend,
|
.first = 0,
|
||||||
|
.nr = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
int pcmcia_badge4_init(struct device *dev)
|
int pcmcia_badge4_init(struct device *dev)
|
||||||
@ -146,7 +143,9 @@ int pcmcia_badge4_init(struct device *dev)
|
|||||||
__func__,
|
__func__,
|
||||||
badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
|
badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
|
||||||
|
|
||||||
ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2);
|
sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
|
||||||
|
ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
|
||||||
|
sa11xx_drv_pcmcia_add_one);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
|
|||||||
|
|
||||||
static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
skt->irq = CERF_IRQ_GPIO_CF_IRQ;
|
skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ;
|
||||||
|
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,16 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
|
|||||||
|
|
||||||
static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
|
static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
return soc_common_drv_pcmcia_remove(&dev->dev);
|
struct skt_dev_info *sinfo = platform_get_drvdata(dev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
platform_set_drvdata(dev, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < sinfo->nskt; i++)
|
||||||
|
soc_pcmcia_remove_one(&sinfo->skt[i]);
|
||||||
|
|
||||||
|
kfree(sinfo);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
|
static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
|
||||||
|
@ -25,8 +25,8 @@ static struct pcmcia_irqs irqs[] = {
|
|||||||
|
|
||||||
static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
skt->irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
|
skt->socket.pci_irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
|
||||||
: IRQ_GPIO_H3600_PCMCIA_IRQ0;
|
: IRQ_GPIO_H3600_PCMCIA_IRQ0;
|
||||||
|
|
||||||
|
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
|
@ -22,25 +22,10 @@
|
|||||||
#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3)
|
#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3)
|
||||||
#define SOCKET1_3V GPIO_GPIO3
|
#define SOCKET1_3V GPIO_GPIO3
|
||||||
|
|
||||||
static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|
||||||
{
|
|
||||||
unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* What is all this crap for?
|
|
||||||
*/
|
|
||||||
GRER |= 0x00000002;
|
|
||||||
/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
|
|
||||||
sa1111_set_io_dir(SA1111_DEV(skt->dev), pin, 0, 0);
|
|
||||||
sa1111_set_io(SA1111_DEV(skt->dev), pin, 0);
|
|
||||||
sa1111_set_sleep_io(SA1111_DEV(skt->dev), pin, 0);
|
|
||||||
|
|
||||||
return sa1111_pcmcia_hw_init(skt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
|
jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
|
||||||
{
|
{
|
||||||
|
struct sa1111_pcmcia_socket *s = to_skt(skt);
|
||||||
unsigned int pa_dwr_mask, pa_dwr_set;
|
unsigned int pa_dwr_mask, pa_dwr_set;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -97,7 +82,7 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
|
sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,21 +91,30 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
|
|||||||
|
|
||||||
static struct pcmcia_low_level jornada720_pcmcia_ops = {
|
static struct pcmcia_low_level jornada720_pcmcia_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.hw_init = jornada720_pcmcia_hw_init,
|
|
||||||
.hw_shutdown = sa1111_pcmcia_hw_shutdown,
|
|
||||||
.socket_state = sa1111_pcmcia_socket_state,
|
|
||||||
.configure_socket = jornada720_pcmcia_configure_socket,
|
.configure_socket = jornada720_pcmcia_configure_socket,
|
||||||
|
|
||||||
.socket_init = sa1111_pcmcia_socket_init,
|
.socket_init = sa1111_pcmcia_socket_init,
|
||||||
.socket_suspend = sa1111_pcmcia_socket_suspend,
|
.first = 0,
|
||||||
|
.nr = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
int __devinit pcmcia_jornada720_init(struct device *dev)
|
int __devinit pcmcia_jornada720_init(struct device *dev)
|
||||||
{
|
{
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
|
|
||||||
if (machine_is_jornada720())
|
if (machine_is_jornada720()) {
|
||||||
ret = sa11xx_drv_pcmcia_probe(dev, &jornada720_pcmcia_ops, 0, 2);
|
unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
|
||||||
|
|
||||||
|
GRER |= 0x00000002;
|
||||||
|
|
||||||
|
/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
|
||||||
|
sa1111_set_io_dir(dev, pin, 0, 0);
|
||||||
|
sa1111_set_io(dev, pin, 0);
|
||||||
|
sa1111_set_sleep_io(dev, pin, 0);
|
||||||
|
|
||||||
|
sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
|
||||||
|
ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
|
||||||
|
sa11xx_drv_pcmcia_add_one);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
static int
|
static int
|
||||||
neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
|
neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
|
||||||
{
|
{
|
||||||
|
struct sa1111_pcmcia_socket *s = to_skt(skt);
|
||||||
unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
|
unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -99,7 +100,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
|
|||||||
NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
|
NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
|
sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -115,12 +116,10 @@ static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
|
|||||||
|
|
||||||
static struct pcmcia_low_level neponset_pcmcia_ops = {
|
static struct pcmcia_low_level neponset_pcmcia_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.hw_init = sa1111_pcmcia_hw_init,
|
|
||||||
.hw_shutdown = sa1111_pcmcia_hw_shutdown,
|
|
||||||
.socket_state = sa1111_pcmcia_socket_state,
|
|
||||||
.configure_socket = neponset_pcmcia_configure_socket,
|
.configure_socket = neponset_pcmcia_configure_socket,
|
||||||
.socket_init = neponset_pcmcia_socket_init,
|
.socket_init = neponset_pcmcia_socket_init,
|
||||||
.socket_suspend = sa1111_pcmcia_socket_suspend,
|
.first = 0,
|
||||||
|
.nr = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
int pcmcia_neponset_init(struct sa1111_dev *sadev)
|
int pcmcia_neponset_init(struct sa1111_dev *sadev)
|
||||||
@ -135,7 +134,9 @@ int pcmcia_neponset_init(struct sa1111_dev *sadev)
|
|||||||
sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
|
sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
|
||||||
sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
|
sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
|
||||||
sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
|
sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
|
||||||
ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2);
|
sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
|
||||||
|
ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
|
||||||
|
sa11xx_drv_pcmcia_add_one);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -28,7 +28,7 @@ static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 |
|
GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 |
|
||||||
SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
|
SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
|
||||||
|
|
||||||
skt->irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
|
skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
|
||||||
|
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|||||||
|
|
||||||
clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
|
clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
|
||||||
|
|
||||||
skt->irq = IRQ_GPIO_CF_IRQ;
|
skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
|
||||||
|
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
@ -28,23 +28,20 @@ static struct pcmcia_irqs irqs[] = {
|
|||||||
{ 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" },
|
{ 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" },
|
||||||
};
|
};
|
||||||
|
|
||||||
int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
if (skt->irq == NO_IRQ)
|
|
||||||
skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
|
|
||||||
|
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
|
static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
|
void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
|
||||||
{
|
{
|
||||||
struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
|
struct sa1111_pcmcia_socket *s = to_skt(skt);
|
||||||
unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR);
|
unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR);
|
||||||
|
|
||||||
switch (skt->nr) {
|
switch (skt->nr) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -71,7 +68,7 @@ void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_sta
|
|||||||
|
|
||||||
int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
|
int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
|
||||||
{
|
{
|
||||||
struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
|
struct sa1111_pcmcia_socket *s = to_skt(skt);
|
||||||
unsigned int pccr_skt_mask, pccr_set_mask, val;
|
unsigned int pccr_skt_mask, pccr_set_mask, val;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
@ -100,10 +97,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
|
|||||||
pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
|
pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
val = sa1111_readl(sadev->mapbase + SA1111_PCCR);
|
val = sa1111_readl(s->dev->mapbase + SA1111_PCCR);
|
||||||
val &= ~pccr_skt_mask;
|
val &= ~pccr_skt_mask;
|
||||||
val |= pccr_set_mask & pccr_skt_mask;
|
val |= pccr_set_mask & pccr_skt_mask;
|
||||||
sa1111_writel(val, sadev->mapbase + SA1111_PCCR);
|
sa1111_writel(val, s->dev->mapbase + SA1111_PCCR);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -114,15 +111,51 @@ void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
|
|||||||
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
|
static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
|
||||||
|
int (*add)(struct soc_pcmcia_socket *))
|
||||||
|
{
|
||||||
|
struct sa1111_pcmcia_socket *s;
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
ops->hw_init = sa1111_pcmcia_hw_init;
|
||||||
|
ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
|
||||||
|
ops->socket_state = sa1111_pcmcia_socket_state;
|
||||||
|
ops->socket_suspend = sa1111_pcmcia_socket_suspend;
|
||||||
|
|
||||||
|
for (i = 0; i < ops->nr; i++) {
|
||||||
|
s = kzalloc(sizeof(*s), GFP_KERNEL);
|
||||||
|
if (!s)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
s->soc.nr = ops->first + i;
|
||||||
|
s->soc.ops = ops;
|
||||||
|
s->soc.socket.owner = ops->owner;
|
||||||
|
s->soc.socket.dev.parent = &dev->dev;
|
||||||
|
s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
|
||||||
|
s->dev = dev;
|
||||||
|
|
||||||
|
ret = add(&s->soc);
|
||||||
|
if (ret == 0) {
|
||||||
|
s->next = dev_get_drvdata(&dev->dev);
|
||||||
|
dev_set_drvdata(&dev->dev, s);
|
||||||
|
} else
|
||||||
|
kfree(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int pcmcia_probe(struct sa1111_dev *dev)
|
static int pcmcia_probe(struct sa1111_dev *dev)
|
||||||
{
|
{
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
|
||||||
|
dev_set_drvdata(&dev->dev, NULL);
|
||||||
|
|
||||||
if (!request_mem_region(dev->res.start, 512,
|
if (!request_mem_region(dev->res.start, 512,
|
||||||
SA1111_DRIVER_NAME(dev)))
|
SA1111_DRIVER_NAME(dev)))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
@ -152,7 +185,15 @@ static int pcmcia_probe(struct sa1111_dev *dev)
|
|||||||
|
|
||||||
static int __devexit pcmcia_remove(struct sa1111_dev *dev)
|
static int __devexit pcmcia_remove(struct sa1111_dev *dev)
|
||||||
{
|
{
|
||||||
soc_common_drv_pcmcia_remove(&dev->dev);
|
struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev);
|
||||||
|
|
||||||
|
dev_set_drvdata(&dev->dev, NULL);
|
||||||
|
|
||||||
|
for (; next = s->next, s; s = next) {
|
||||||
|
soc_pcmcia_remove_one(&s->soc);
|
||||||
|
kfree(s);
|
||||||
|
}
|
||||||
|
|
||||||
release_mem_region(dev->res.start, 512);
|
release_mem_region(dev->res.start, 512);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,23 @@
|
|||||||
#include "soc_common.h"
|
#include "soc_common.h"
|
||||||
#include "sa11xx_base.h"
|
#include "sa11xx_base.h"
|
||||||
|
|
||||||
extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *);
|
struct sa1111_pcmcia_socket {
|
||||||
extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *);
|
struct soc_pcmcia_socket soc;
|
||||||
|
struct sa1111_dev *dev;
|
||||||
|
struct sa1111_pcmcia_socket *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s)
|
||||||
|
{
|
||||||
|
return container_of(s, struct sa1111_pcmcia_socket, soc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
|
||||||
|
int (*add)(struct soc_pcmcia_socket *));
|
||||||
|
|
||||||
extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
|
extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
|
||||||
extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
|
extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
|
||||||
extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
|
extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
|
||||||
extern void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *);
|
|
||||||
|
|
||||||
extern int pcmcia_badge4_init(struct device *);
|
extern int pcmcia_badge4_init(struct device *);
|
||||||
extern int pcmcia_jornada720_init(struct device *);
|
extern int pcmcia_jornada720_init(struct device *);
|
||||||
|
@ -171,47 +171,34 @@ static const char *skt_names[] = {
|
|||||||
#define SKT_DEV_INFO_SIZE(n) \
|
#define SKT_DEV_INFO_SIZE(n) \
|
||||||
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
|
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
|
||||||
|
|
||||||
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
|
int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
|
||||||
int first, int nr)
|
|
||||||
{
|
{
|
||||||
struct skt_dev_info *sinfo;
|
skt->res_skt.start = _PCMCIA(skt->nr);
|
||||||
struct soc_pcmcia_socket *skt;
|
skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
|
||||||
int i;
|
skt->res_skt.name = skt_names[skt->nr];
|
||||||
|
skt->res_skt.flags = IORESOURCE_MEM;
|
||||||
|
|
||||||
sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
|
skt->res_io.start = _PCMCIAIO(skt->nr);
|
||||||
if (!sinfo)
|
skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
|
||||||
return -ENOMEM;
|
skt->res_io.name = "io";
|
||||||
|
skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
||||||
|
|
||||||
sinfo->nskt = nr;
|
skt->res_mem.start = _PCMCIAMem(skt->nr);
|
||||||
|
skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
|
||||||
|
skt->res_mem.name = "memory";
|
||||||
|
skt->res_mem.flags = IORESOURCE_MEM;
|
||||||
|
|
||||||
/* Initiliaze processor specific parameters */
|
skt->res_attr.start = _PCMCIAAttr(skt->nr);
|
||||||
for (i = 0; i < nr; i++) {
|
skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
|
||||||
skt = &sinfo->skt[i];
|
skt->res_attr.name = "attribute";
|
||||||
|
skt->res_attr.flags = IORESOURCE_MEM;
|
||||||
|
|
||||||
skt->nr = first + i;
|
return soc_pcmcia_add_one(skt);
|
||||||
skt->irq = NO_IRQ;
|
}
|
||||||
|
EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one);
|
||||||
skt->res_skt.start = _PCMCIA(skt->nr);
|
|
||||||
skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
|
|
||||||
skt->res_skt.name = skt_names[skt->nr];
|
|
||||||
skt->res_skt.flags = IORESOURCE_MEM;
|
|
||||||
|
|
||||||
skt->res_io.start = _PCMCIAIO(skt->nr);
|
|
||||||
skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
|
|
||||||
skt->res_io.name = "io";
|
|
||||||
skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
|
||||||
|
|
||||||
skt->res_mem.start = _PCMCIAMem(skt->nr);
|
|
||||||
skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
|
|
||||||
skt->res_mem.name = "memory";
|
|
||||||
skt->res_mem.flags = IORESOURCE_MEM;
|
|
||||||
|
|
||||||
skt->res_attr.start = _PCMCIAAttr(skt->nr);
|
|
||||||
skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
|
|
||||||
skt->res_attr.name = "attribute";
|
|
||||||
skt->res_attr.flags = IORESOURCE_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* set default MECR calculation if the board specific
|
* set default MECR calculation if the board specific
|
||||||
* code did not specify one...
|
* code did not specify one...
|
||||||
@ -225,8 +212,48 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
|
|||||||
#ifdef CONFIG_CPU_FREQ
|
#ifdef CONFIG_CPU_FREQ
|
||||||
ops->frequency_change = sa1100_pcmcia_frequency_change;
|
ops->frequency_change = sa1100_pcmcia_frequency_change;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops);
|
||||||
|
|
||||||
return soc_common_drv_pcmcia_probe(dev, ops, sinfo);
|
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
|
||||||
|
int first, int nr)
|
||||||
|
{
|
||||||
|
struct skt_dev_info *sinfo;
|
||||||
|
struct soc_pcmcia_socket *skt;
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
sa11xx_drv_pcmcia_ops(ops);
|
||||||
|
|
||||||
|
sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
|
||||||
|
if (!sinfo)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
sinfo->nskt = nr;
|
||||||
|
|
||||||
|
/* Initiliaze processor specific parameters */
|
||||||
|
for (i = 0; i < nr; i++) {
|
||||||
|
skt = &sinfo->skt[i];
|
||||||
|
|
||||||
|
skt->nr = first + i;
|
||||||
|
skt->ops = ops;
|
||||||
|
skt->socket.owner = ops->owner;
|
||||||
|
skt->socket.dev.parent = dev;
|
||||||
|
skt->socket.pci_irq = NO_IRQ;
|
||||||
|
|
||||||
|
ret = sa11xx_drv_pcmcia_add_one(skt);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
while (--i >= 0)
|
||||||
|
soc_pcmcia_remove_one(&sinfo->skt[i]);
|
||||||
|
kfree(sinfo);
|
||||||
|
} else {
|
||||||
|
dev_set_drvdata(dev, sinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
|
EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
|
||||||
|
|
||||||
|
@ -118,6 +118,8 @@ static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
|
||||||
|
void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
|
||||||
extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
|
extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
|
||||||
|
|
||||||
#endif /* !defined(_PCMCIA_SA1100_H) */
|
#endif /* !defined(_PCMCIA_SA1100_H) */
|
||||||
|
@ -144,10 +144,10 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat
|
|||||||
*/
|
*/
|
||||||
if (skt->irq_state != 1 && state->io_irq) {
|
if (skt->irq_state != 1 && state->io_irq) {
|
||||||
skt->irq_state = 1;
|
skt->irq_state = 1;
|
||||||
set_irq_type(skt->irq, IRQ_TYPE_EDGE_FALLING);
|
set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
|
||||||
} else if (skt->irq_state == 1 && state->io_irq == 0) {
|
} else if (skt->irq_state == 1 && state->io_irq == 0) {
|
||||||
skt->irq_state = 0;
|
skt->irq_state = 0;
|
||||||
set_irq_type(skt->irq, IRQ_TYPE_NONE);
|
set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
skt->cs_state = *state;
|
skt->cs_state = *state;
|
||||||
@ -492,7 +492,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr, ch
|
|||||||
|
|
||||||
p+=sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc);
|
p+=sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc);
|
||||||
p+=sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp);
|
p+=sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp);
|
||||||
p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, skt->irq);
|
p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq,
|
||||||
|
skt->socket.pci_irq);
|
||||||
if (skt->ops->show_timing)
|
if (skt->ops->show_timing)
|
||||||
p+=skt->ops->show_timing(skt, p);
|
p+=skt->ops->show_timing(skt, p);
|
||||||
|
|
||||||
@ -574,7 +575,7 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
|
|||||||
EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
|
EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
|
||||||
|
|
||||||
|
|
||||||
LIST_HEAD(soc_pcmcia_sockets);
|
static LIST_HEAD(soc_pcmcia_sockets);
|
||||||
static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
|
static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_FREQ
|
#ifdef CONFIG_CPU_FREQ
|
||||||
@ -609,177 +610,137 @@ static int soc_pcmcia_cpufreq_register(void)
|
|||||||
"notifier for PCMCIA (%d)\n", ret);
|
"notifier for PCMCIA (%d)\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
fs_initcall(soc_pcmcia_cpufreq_register);
|
||||||
|
|
||||||
static void soc_pcmcia_cpufreq_unregister(void)
|
static void soc_pcmcia_cpufreq_unregister(void)
|
||||||
{
|
{
|
||||||
cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
|
cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
|
||||||
}
|
}
|
||||||
|
module_exit(soc_pcmcia_cpufreq_unregister);
|
||||||
|
|
||||||
#else
|
|
||||||
static int soc_pcmcia_cpufreq_register(void) { return 0; }
|
|
||||||
static void soc_pcmcia_cpufreq_unregister(void) {}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
|
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
|
||||||
struct skt_dev_info *sinfo)
|
|
||||||
{
|
{
|
||||||
struct soc_pcmcia_socket *skt;
|
mutex_lock(&soc_pcmcia_sockets_lock);
|
||||||
int ret, i;
|
del_timer_sync(&skt->poll_timer);
|
||||||
|
|
||||||
|
pcmcia_unregister_socket(&skt->socket);
|
||||||
|
|
||||||
|
flush_scheduled_work();
|
||||||
|
|
||||||
|
skt->ops->hw_shutdown(skt);
|
||||||
|
|
||||||
|
soc_common_pcmcia_config_skt(skt, &dead_socket);
|
||||||
|
|
||||||
|
list_del(&skt->node);
|
||||||
|
mutex_unlock(&soc_pcmcia_sockets_lock);
|
||||||
|
|
||||||
|
iounmap(skt->virt_io);
|
||||||
|
skt->virt_io = NULL;
|
||||||
|
release_resource(&skt->res_attr);
|
||||||
|
release_resource(&skt->res_mem);
|
||||||
|
release_resource(&skt->res_io);
|
||||||
|
release_resource(&skt->res_skt);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(soc_pcmcia_remove_one);
|
||||||
|
|
||||||
|
int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
init_timer(&skt->poll_timer);
|
||||||
|
skt->poll_timer.function = soc_common_pcmcia_poll_event;
|
||||||
|
skt->poll_timer.data = (unsigned long)skt;
|
||||||
|
skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
|
||||||
|
|
||||||
|
ret = request_resource(&iomem_resource, &skt->res_skt);
|
||||||
|
if (ret)
|
||||||
|
goto out_err_1;
|
||||||
|
|
||||||
|
ret = request_resource(&skt->res_skt, &skt->res_io);
|
||||||
|
if (ret)
|
||||||
|
goto out_err_2;
|
||||||
|
|
||||||
|
ret = request_resource(&skt->res_skt, &skt->res_mem);
|
||||||
|
if (ret)
|
||||||
|
goto out_err_3;
|
||||||
|
|
||||||
|
ret = request_resource(&skt->res_skt, &skt->res_attr);
|
||||||
|
if (ret)
|
||||||
|
goto out_err_4;
|
||||||
|
|
||||||
|
skt->virt_io = ioremap(skt->res_io.start, 0x10000);
|
||||||
|
if (skt->virt_io == NULL) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_err_5;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&soc_pcmcia_sockets_lock);
|
mutex_lock(&soc_pcmcia_sockets_lock);
|
||||||
|
|
||||||
|
list_add(&skt->node, &soc_pcmcia_sockets);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise the per-socket structure.
|
* We initialize default socket timing here, because
|
||||||
|
* we are not guaranteed to see a SetIOMap operation at
|
||||||
|
* runtime.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < sinfo->nskt; i++) {
|
skt->ops->set_timing(skt);
|
||||||
skt = &sinfo->skt[i];
|
|
||||||
|
|
||||||
skt->socket.ops = &soc_common_pcmcia_operations;
|
ret = skt->ops->hw_init(skt);
|
||||||
skt->socket.owner = ops->owner;
|
if (ret)
|
||||||
skt->socket.dev.parent = dev;
|
goto out_err_6;
|
||||||
|
|
||||||
init_timer(&skt->poll_timer);
|
skt->socket.ops = &soc_common_pcmcia_operations;
|
||||||
skt->poll_timer.function = soc_common_pcmcia_poll_event;
|
skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
|
||||||
skt->poll_timer.data = (unsigned long)skt;
|
skt->socket.resource_ops = &pccard_static_ops;
|
||||||
skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
|
skt->socket.irq_mask = 0;
|
||||||
|
skt->socket.map_size = PAGE_SIZE;
|
||||||
|
skt->socket.io_offset = (unsigned long)skt->virt_io;
|
||||||
|
|
||||||
skt->dev = dev;
|
skt->status = soc_common_pcmcia_skt_state(skt);
|
||||||
skt->ops = ops;
|
|
||||||
|
|
||||||
ret = request_resource(&iomem_resource, &skt->res_skt);
|
ret = pcmcia_register_socket(&skt->socket);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_err_1;
|
goto out_err_7;
|
||||||
|
|
||||||
ret = request_resource(&skt->res_skt, &skt->res_io);
|
add_timer(&skt->poll_timer);
|
||||||
if (ret)
|
|
||||||
goto out_err_2;
|
|
||||||
|
|
||||||
ret = request_resource(&skt->res_skt, &skt->res_mem);
|
mutex_unlock(&soc_pcmcia_sockets_lock);
|
||||||
if (ret)
|
|
||||||
goto out_err_3;
|
|
||||||
|
|
||||||
ret = request_resource(&skt->res_skt, &skt->res_attr);
|
ret = device_create_file(&skt->socket.dev, &dev_attr_status);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_err_4;
|
goto out_err_8;
|
||||||
|
|
||||||
skt->virt_io = ioremap(skt->res_io.start, 0x10000);
|
return ret;
|
||||||
if (skt->virt_io == NULL) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto out_err_5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list_empty(&soc_pcmcia_sockets))
|
|
||||||
soc_pcmcia_cpufreq_register();
|
|
||||||
|
|
||||||
list_add(&skt->node, &soc_pcmcia_sockets);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We initialize default socket timing here, because
|
|
||||||
* we are not guaranteed to see a SetIOMap operation at
|
|
||||||
* runtime.
|
|
||||||
*/
|
|
||||||
ops->set_timing(skt);
|
|
||||||
|
|
||||||
ret = ops->hw_init(skt);
|
|
||||||
if (ret)
|
|
||||||
goto out_err_6;
|
|
||||||
|
|
||||||
skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
|
|
||||||
skt->socket.resource_ops = &pccard_static_ops;
|
|
||||||
skt->socket.irq_mask = 0;
|
|
||||||
skt->socket.map_size = PAGE_SIZE;
|
|
||||||
skt->socket.pci_irq = skt->irq;
|
|
||||||
skt->socket.io_offset = (unsigned long)skt->virt_io;
|
|
||||||
|
|
||||||
skt->status = soc_common_pcmcia_skt_state(skt);
|
|
||||||
|
|
||||||
ret = pcmcia_register_socket(&skt->socket);
|
|
||||||
if (ret)
|
|
||||||
goto out_err_7;
|
|
||||||
|
|
||||||
WARN_ON(skt->socket.sock != i);
|
|
||||||
|
|
||||||
add_timer(&skt->poll_timer);
|
|
||||||
|
|
||||||
ret = device_create_file(&skt->socket.dev, &dev_attr_status);
|
|
||||||
if (ret)
|
|
||||||
goto out_err_8;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_set_drvdata(dev, sinfo);
|
|
||||||
ret = 0;
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
do {
|
|
||||||
skt = &sinfo->skt[i];
|
|
||||||
|
|
||||||
device_remove_file(&skt->socket.dev, &dev_attr_status);
|
|
||||||
out_err_8:
|
out_err_8:
|
||||||
del_timer_sync(&skt->poll_timer);
|
mutex_lock(&soc_pcmcia_sockets_lock);
|
||||||
pcmcia_unregister_socket(&skt->socket);
|
del_timer_sync(&skt->poll_timer);
|
||||||
|
pcmcia_unregister_socket(&skt->socket);
|
||||||
|
|
||||||
out_err_7:
|
out_err_7:
|
||||||
flush_scheduled_work();
|
flush_scheduled_work();
|
||||||
|
|
||||||
ops->hw_shutdown(skt);
|
skt->ops->hw_shutdown(skt);
|
||||||
out_err_6:
|
out_err_6:
|
||||||
list_del(&skt->node);
|
list_del(&skt->node);
|
||||||
iounmap(skt->virt_io);
|
|
||||||
out_err_5:
|
|
||||||
release_resource(&skt->res_attr);
|
|
||||||
out_err_4:
|
|
||||||
release_resource(&skt->res_mem);
|
|
||||||
out_err_3:
|
|
||||||
release_resource(&skt->res_io);
|
|
||||||
out_err_2:
|
|
||||||
release_resource(&skt->res_skt);
|
|
||||||
out_err_1:
|
|
||||||
i--;
|
|
||||||
} while (i > 0);
|
|
||||||
|
|
||||||
kfree(sinfo);
|
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&soc_pcmcia_sockets_lock);
|
mutex_unlock(&soc_pcmcia_sockets_lock);
|
||||||
|
iounmap(skt->virt_io);
|
||||||
|
out_err_5:
|
||||||
|
release_resource(&skt->res_attr);
|
||||||
|
out_err_4:
|
||||||
|
release_resource(&skt->res_mem);
|
||||||
|
out_err_3:
|
||||||
|
release_resource(&skt->res_io);
|
||||||
|
out_err_2:
|
||||||
|
release_resource(&skt->res_skt);
|
||||||
|
out_err_1:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(soc_pcmcia_add_one);
|
||||||
|
|
||||||
int soc_common_drv_pcmcia_remove(struct device *dev)
|
MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
|
||||||
{
|
MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support");
|
||||||
struct skt_dev_info *sinfo = dev_get_drvdata(dev);
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
int i;
|
|
||||||
|
|
||||||
dev_set_drvdata(dev, NULL);
|
|
||||||
|
|
||||||
mutex_lock(&soc_pcmcia_sockets_lock);
|
|
||||||
for (i = 0; i < sinfo->nskt; i++) {
|
|
||||||
struct soc_pcmcia_socket *skt = &sinfo->skt[i];
|
|
||||||
|
|
||||||
del_timer_sync(&skt->poll_timer);
|
|
||||||
|
|
||||||
pcmcia_unregister_socket(&skt->socket);
|
|
||||||
|
|
||||||
flush_scheduled_work();
|
|
||||||
|
|
||||||
skt->ops->hw_shutdown(skt);
|
|
||||||
|
|
||||||
soc_common_pcmcia_config_skt(skt, &dead_socket);
|
|
||||||
|
|
||||||
list_del(&skt->node);
|
|
||||||
iounmap(skt->virt_io);
|
|
||||||
skt->virt_io = NULL;
|
|
||||||
release_resource(&skt->res_attr);
|
|
||||||
release_resource(&skt->res_mem);
|
|
||||||
release_resource(&skt->res_io);
|
|
||||||
release_resource(&skt->res_skt);
|
|
||||||
}
|
|
||||||
if (list_empty(&soc_pcmcia_sockets))
|
|
||||||
soc_pcmcia_cpufreq_unregister();
|
|
||||||
|
|
||||||
mutex_unlock(&soc_pcmcia_sockets_lock);
|
|
||||||
|
|
||||||
kfree(sinfo);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);
|
|
||||||
|
@ -30,14 +30,12 @@ struct soc_pcmcia_socket {
|
|||||||
/*
|
/*
|
||||||
* Info from low level handler
|
* Info from low level handler
|
||||||
*/
|
*/
|
||||||
struct device *dev;
|
|
||||||
unsigned int nr;
|
unsigned int nr;
|
||||||
unsigned int irq;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core PCMCIA state
|
* Core PCMCIA state
|
||||||
*/
|
*/
|
||||||
struct pcmcia_low_level *ops;
|
const struct pcmcia_low_level *ops;
|
||||||
|
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
socket_state_t cs_state;
|
socket_state_t cs_state;
|
||||||
@ -135,10 +133,8 @@ extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_
|
|||||||
extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
|
extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
|
||||||
|
|
||||||
|
|
||||||
extern struct list_head soc_pcmcia_sockets;
|
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
|
||||||
|
int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
|
||||||
extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo);
|
|
||||||
extern int soc_common_drv_pcmcia_remove(struct device *dev);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
#ifdef CONFIG_PCMCIA_DEBUG
|
||||||
|
@ -55,21 +55,6 @@
|
|||||||
#include <pcmcia/ss.h>
|
#include <pcmcia/ss.h>
|
||||||
#include "tcic.h"
|
#include "tcic.h"
|
||||||
|
|
||||||
#ifdef CONFIG_PCMCIA_DEBUG
|
|
||||||
static int pc_debug;
|
|
||||||
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
static const char version[] =
|
|
||||||
"tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
|
|
||||||
|
|
||||||
#define debug(lvl, fmt, arg...) do { \
|
|
||||||
if (pc_debug > (lvl)) \
|
|
||||||
printk(KERN_DEBUG "tcic: " fmt , ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
#define debug(lvl, fmt, arg...) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
||||||
MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
|
MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
|
||||||
MODULE_LICENSE("Dual MPL/GPL");
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
@ -574,7 +559,7 @@ static irqreturn_t tcic_interrupt(int irq, void *dev)
|
|||||||
} else
|
} else
|
||||||
active = 1;
|
active = 1;
|
||||||
|
|
||||||
debug(2, "tcic_interrupt()\n");
|
pr_debug("tcic_interrupt()\n");
|
||||||
|
|
||||||
for (i = 0; i < sockets; i++) {
|
for (i = 0; i < sockets; i++) {
|
||||||
psock = socket_table[i].psock;
|
psock = socket_table[i].psock;
|
||||||
@ -611,13 +596,13 @@ static irqreturn_t tcic_interrupt(int irq, void *dev)
|
|||||||
}
|
}
|
||||||
active = 0;
|
active = 0;
|
||||||
|
|
||||||
debug(2, "interrupt done\n");
|
pr_debug("interrupt done\n");
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
} /* tcic_interrupt */
|
} /* tcic_interrupt */
|
||||||
|
|
||||||
static void tcic_timer(u_long data)
|
static void tcic_timer(u_long data)
|
||||||
{
|
{
|
||||||
debug(2, "tcic_timer()\n");
|
pr_debug("tcic_timer()\n");
|
||||||
tcic_timer_pending = 0;
|
tcic_timer_pending = 0;
|
||||||
tcic_interrupt(0, NULL);
|
tcic_interrupt(0, NULL);
|
||||||
} /* tcic_timer */
|
} /* tcic_timer */
|
||||||
@ -644,7 +629,7 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
|
|||||||
reg = tcic_getb(TCIC_PWR);
|
reg = tcic_getb(TCIC_PWR);
|
||||||
if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
|
if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
|
||||||
*value |= SS_POWERON;
|
*value |= SS_POWERON;
|
||||||
debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
|
dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
|
||||||
return 0;
|
return 0;
|
||||||
} /* tcic_get_status */
|
} /* tcic_get_status */
|
||||||
|
|
||||||
@ -656,7 +641,7 @@ static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
|
|||||||
u_char reg;
|
u_char reg;
|
||||||
u_short scf1, scf2;
|
u_short scf1, scf2;
|
||||||
|
|
||||||
debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
|
||||||
"io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
|
"io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
|
||||||
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
|
||||||
tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
|
tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
|
||||||
@ -731,7 +716,7 @@ static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
|
|||||||
u_int addr;
|
u_int addr;
|
||||||
u_short base, len, ioctl;
|
u_short base, len, ioctl;
|
||||||
|
|
||||||
debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
|
dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
|
"%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
|
||||||
(unsigned long long)io->start, (unsigned long long)io->stop);
|
(unsigned long long)io->start, (unsigned long long)io->stop);
|
||||||
if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
|
if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
|
||||||
@ -768,7 +753,7 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
|
|||||||
u_short addr, ctl;
|
u_short addr, ctl;
|
||||||
u_long base, len, mmap;
|
u_long base, len, mmap;
|
||||||
|
|
||||||
debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
|
dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
|
||||||
"%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
|
"%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
|
||||||
mem->speed, (unsigned long long)mem->res->start,
|
mem->speed, (unsigned long long)mem->res->start,
|
||||||
(unsigned long long)mem->res->end, mem->card_start);
|
(unsigned long long)mem->res->end, mem->card_start);
|
||||||
|
@ -114,22 +114,17 @@ static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
|
|||||||
reg_zv |= TOPIC97_ZV_CONTROL_ENABLE;
|
reg_zv |= TOPIC97_ZV_CONTROL_ENABLE;
|
||||||
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
|
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
|
||||||
|
|
||||||
reg = config_readb(socket, TOPIC97_MISC2);
|
|
||||||
reg |= TOPIC97_MISC2_ZV_ENABLE;
|
|
||||||
config_writeb(socket, TOPIC97_MISC2, reg);
|
|
||||||
|
|
||||||
/* not sure this is needed, doc is unclear */
|
|
||||||
#if 0
|
|
||||||
reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
|
reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
|
||||||
reg |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL;
|
reg |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL;
|
||||||
config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
|
config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
|
||||||
#endif
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE;
|
reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE;
|
||||||
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
|
config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
|
||||||
}
|
|
||||||
|
|
||||||
|
reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
|
||||||
|
reg &= ~(TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL);
|
||||||
|
config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int topic97_override(struct yenta_socket *socket)
|
static int topic97_override(struct yenta_socket *socket)
|
||||||
|
@ -54,15 +54,6 @@
|
|||||||
#include <pcmcia/cistpl.h>
|
#include <pcmcia/cistpl.h>
|
||||||
#include <pcmcia/ds.h>
|
#include <pcmcia/ds.h>
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"aha152x_cs.c 1.54 2000/06/12 21:27:25 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -103,7 +94,7 @@ static int aha152x_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
scsi_info_t *info;
|
scsi_info_t *info;
|
||||||
|
|
||||||
DEBUG(0, "aha152x_attach()\n");
|
dev_dbg(&link->dev, "aha152x_attach()\n");
|
||||||
|
|
||||||
/* Create new SCSI device */
|
/* Create new SCSI device */
|
||||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||||
@ -115,7 +106,6 @@ static int aha152x_probe(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
link->io.IOAddrLines = 10;
|
link->io.IOAddrLines = 10;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.Present = PRESENT_OPTION;
|
link->conf.Present = PRESENT_OPTION;
|
||||||
@ -127,7 +117,7 @@ static int aha152x_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void aha152x_detach(struct pcmcia_device *link)
|
static void aha152x_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "aha152x_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "aha152x_detach\n");
|
||||||
|
|
||||||
aha152x_release_cs(link);
|
aha152x_release_cs(link);
|
||||||
|
|
||||||
@ -137,9 +127,6 @@ static void aha152x_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int aha152x_config_check(struct pcmcia_device *p_dev,
|
static int aha152x_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -164,19 +151,22 @@ static int aha152x_config_cs(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
scsi_info_t *info = link->priv;
|
scsi_info_t *info = link->priv;
|
||||||
struct aha152x_setup s;
|
struct aha152x_setup s;
|
||||||
int last_ret, last_fn;
|
int ret;
|
||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
|
|
||||||
DEBUG(0, "aha152x_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "aha152x_config\n");
|
||||||
|
|
||||||
last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
|
ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIO, last_ret);
|
goto failed;
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* Set configuration options for the aha152x driver */
|
/* Set configuration options for the aha152x driver */
|
||||||
memset(&s, 0, sizeof(s));
|
memset(&s, 0, sizeof(s));
|
||||||
@ -194,7 +184,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
|
|||||||
host = aha152x_probe_one(&s);
|
host = aha152x_probe_one(&s);
|
||||||
if (host == NULL) {
|
if (host == NULL) {
|
||||||
printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
|
printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||||
@ -203,8 +193,6 @@ static int aha152x_config_cs(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
aha152x_release_cs(link);
|
aha152x_release_cs(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -59,16 +59,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
|||||||
MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
|
MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
|
||||||
MODULE_LICENSE("Dual MPL/GPL");
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"fdomain_cs.c 1.47 2001/10/13 00:08:52 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
typedef struct scsi_info_t {
|
typedef struct scsi_info_t {
|
||||||
@ -86,7 +76,7 @@ static int fdomain_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
scsi_info_t *info;
|
scsi_info_t *info;
|
||||||
|
|
||||||
DEBUG(0, "fdomain_attach()\n");
|
dev_dbg(&link->dev, "fdomain_attach()\n");
|
||||||
|
|
||||||
/* Create new SCSI device */
|
/* Create new SCSI device */
|
||||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||||
@ -99,7 +89,6 @@ static int fdomain_probe(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
link->io.IOAddrLines = 10;
|
link->io.IOAddrLines = 10;
|
||||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.Present = PRESENT_OPTION;
|
link->conf.Present = PRESENT_OPTION;
|
||||||
@ -111,7 +100,7 @@ static int fdomain_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void fdomain_detach(struct pcmcia_device *link)
|
static void fdomain_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "fdomain_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "fdomain_detach\n");
|
||||||
|
|
||||||
fdomain_release(link);
|
fdomain_release(link);
|
||||||
|
|
||||||
@ -120,9 +109,6 @@ static void fdomain_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int fdomain_config_check(struct pcmcia_device *p_dev,
|
static int fdomain_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -137,20 +123,22 @@ static int fdomain_config_check(struct pcmcia_device *p_dev,
|
|||||||
static int fdomain_config(struct pcmcia_device *link)
|
static int fdomain_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
scsi_info_t *info = link->priv;
|
scsi_info_t *info = link->priv;
|
||||||
int last_ret, last_fn;
|
int ret;
|
||||||
char str[22];
|
char str[22];
|
||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
|
|
||||||
DEBUG(0, "fdomain_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "fdomain_config\n");
|
||||||
|
|
||||||
last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
|
ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* A bad hack... */
|
/* A bad hack... */
|
||||||
release_region(link->io.BasePort1, link->io.NumPorts1);
|
release_region(link->io.BasePort1, link->io.NumPorts1);
|
||||||
@ -162,11 +150,11 @@ static int fdomain_config(struct pcmcia_device *link)
|
|||||||
host = __fdomain_16x0_detect(&fdomain_driver_template);
|
host = __fdomain_16x0_detect(&fdomain_driver_template);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
|
printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scsi_add_host(host, NULL))
|
if (scsi_add_host(host, NULL))
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
scsi_scan_host(host);
|
scsi_scan_host(host);
|
||||||
|
|
||||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||||
@ -175,8 +163,6 @@ static int fdomain_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
fdomain_release(link);
|
fdomain_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -188,7 +174,7 @@ static void fdomain_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
scsi_info_t *info = link->priv;
|
scsi_info_t *info = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "fdomain_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "fdomain_release\n");
|
||||||
|
|
||||||
scsi_remove_host(info->host);
|
scsi_remove_host(info->host);
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
|
@ -1564,12 +1564,10 @@ static int nsp_cs_probe(struct pcmcia_device *link)
|
|||||||
link->io.IOAddrLines = 10; /* not used */
|
link->io.IOAddrLines = 10; /* not used */
|
||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
|
|
||||||
/* Interrupt handler */
|
/* Interrupt handler */
|
||||||
link->irq.Handler = &nspintr;
|
link->irq.Handler = &nspintr;
|
||||||
link->irq.Instance = info;
|
|
||||||
link->irq.Attributes |= IRQF_SHARED;
|
link->irq.Attributes |= IRQF_SHARED;
|
||||||
|
|
||||||
/* General socket configuration */
|
/* General socket configuration */
|
||||||
@ -1684,10 +1682,10 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
|
|||||||
if (cfg_mem->req.Size < 0x1000)
|
if (cfg_mem->req.Size < 0x1000)
|
||||||
cfg_mem->req.Size = 0x1000;
|
cfg_mem->req.Size = 0x1000;
|
||||||
cfg_mem->req.AccessSpeed = 0;
|
cfg_mem->req.AccessSpeed = 0;
|
||||||
if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
|
if (pcmcia_request_window(p_dev, &cfg_mem->req, &p_dev->win) != 0)
|
||||||
goto next_entry;
|
goto next_entry;
|
||||||
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
|
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
|
||||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
|
||||||
goto next_entry;
|
goto next_entry;
|
||||||
|
|
||||||
cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
|
cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
|
||||||
|
@ -62,15 +62,6 @@
|
|||||||
|
|
||||||
static char qlogic_name[] = "qlogic_cs";
|
static char qlogic_name[] = "qlogic_cs";
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct scsi_host_template qlogicfas_driver_template = {
|
static struct scsi_host_template qlogicfas_driver_template = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.name = qlogic_name,
|
.name = qlogic_name,
|
||||||
@ -159,7 +150,7 @@ static int qlogic_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
scsi_info_t *info;
|
scsi_info_t *info;
|
||||||
|
|
||||||
DEBUG(0, "qlogic_attach()\n");
|
dev_dbg(&link->dev, "qlogic_attach()\n");
|
||||||
|
|
||||||
/* Create new SCSI device */
|
/* Create new SCSI device */
|
||||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||||
@ -171,7 +162,6 @@ static int qlogic_probe(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
link->io.IOAddrLines = 10;
|
link->io.IOAddrLines = 10;
|
||||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
link->conf.Present = PRESENT_OPTION;
|
link->conf.Present = PRESENT_OPTION;
|
||||||
@ -183,7 +173,7 @@ static int qlogic_probe(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void qlogic_detach(struct pcmcia_device *link)
|
static void qlogic_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "qlogic_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "qlogic_detach\n");
|
||||||
|
|
||||||
qlogic_release(link);
|
qlogic_release(link);
|
||||||
kfree(link->priv);
|
kfree(link->priv);
|
||||||
@ -192,9 +182,6 @@ static void qlogic_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int qlogic_config_check(struct pcmcia_device *p_dev,
|
static int qlogic_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -213,19 +200,22 @@ static int qlogic_config_check(struct pcmcia_device *p_dev,
|
|||||||
static int qlogic_config(struct pcmcia_device * link)
|
static int qlogic_config(struct pcmcia_device * link)
|
||||||
{
|
{
|
||||||
scsi_info_t *info = link->priv;
|
scsi_info_t *info = link->priv;
|
||||||
int last_ret, last_fn;
|
int ret;
|
||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
|
|
||||||
DEBUG(0, "qlogic_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "qlogic_config\n");
|
||||||
|
|
||||||
last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
|
ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
|
if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
|
||||||
/* set ATAcmd */
|
/* set ATAcmd */
|
||||||
@ -244,7 +234,7 @@ static int qlogic_config(struct pcmcia_device * link)
|
|||||||
|
|
||||||
if (!host) {
|
if (!host) {
|
||||||
printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
|
printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
|
||||||
goto cs_failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
sprintf(info->node.dev_name, "scsi%d", host->host_no);
|
||||||
@ -253,12 +243,9 @@ static int qlogic_config(struct pcmcia_device * link)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
pcmcia_disable_device(link);
|
|
||||||
failed:
|
failed:
|
||||||
|
pcmcia_disable_device(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
} /* qlogic_config */
|
} /* qlogic_config */
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
@ -267,7 +254,7 @@ static void qlogic_release(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
scsi_info_t *info = link->priv;
|
scsi_info_t *info = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "qlogic_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "qlogic_release\n");
|
||||||
|
|
||||||
scsi_remove_host(info->host);
|
scsi_remove_host(info->host);
|
||||||
|
|
||||||
|
@ -77,17 +77,6 @@
|
|||||||
#include <pcmcia/ds.h>
|
#include <pcmcia/ds.h>
|
||||||
#include <pcmcia/ciscode.h>
|
#include <pcmcia/ciscode.h>
|
||||||
|
|
||||||
/* ================================================================== */
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"sym53c500_cs.c 0.9c 2004/10/27 (Bob Tracy)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ================================================================== */
|
/* ================================================================== */
|
||||||
|
|
||||||
@ -525,7 +514,7 @@ SYM53C500_release(struct pcmcia_device *link)
|
|||||||
struct scsi_info_t *info = link->priv;
|
struct scsi_info_t *info = link->priv;
|
||||||
struct Scsi_Host *shost = info->host;
|
struct Scsi_Host *shost = info->host;
|
||||||
|
|
||||||
DEBUG(0, "SYM53C500_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "SYM53C500_release\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do this before releasing/freeing resources.
|
* Do this before releasing/freeing resources.
|
||||||
@ -697,9 +686,6 @@ static struct scsi_host_template sym53c500_driver_template = {
|
|||||||
.shost_attrs = SYM53C500_shost_attrs
|
.shost_attrs = SYM53C500_shost_attrs
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CS_CHECK(fn, ret) \
|
|
||||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|
||||||
|
|
||||||
static int SYM53C500_config_check(struct pcmcia_device *p_dev,
|
static int SYM53C500_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cfg,
|
cistpl_cftable_entry_t *cfg,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -719,24 +705,27 @@ static int
|
|||||||
SYM53C500_config(struct pcmcia_device *link)
|
SYM53C500_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct scsi_info_t *info = link->priv;
|
struct scsi_info_t *info = link->priv;
|
||||||
int last_ret, last_fn;
|
int ret;
|
||||||
int irq_level, port_base;
|
int irq_level, port_base;
|
||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
struct scsi_host_template *tpnt = &sym53c500_driver_template;
|
struct scsi_host_template *tpnt = &sym53c500_driver_template;
|
||||||
struct sym53c500_data *data;
|
struct sym53c500_data *data;
|
||||||
|
|
||||||
DEBUG(0, "SYM53C500_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "SYM53C500_config\n");
|
||||||
|
|
||||||
info->manf_id = link->manf_id;
|
info->manf_id = link->manf_id;
|
||||||
|
|
||||||
last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
|
ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIO, last_ret);
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
|
||||||
|
|
||||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* That's the trouble with copying liberally from another driver.
|
* That's the trouble with copying liberally from another driver.
|
||||||
@ -824,8 +813,6 @@ SYM53C500_config(struct pcmcia_device *link)
|
|||||||
printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
|
printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
SYM53C500_release(link);
|
SYM53C500_release(link);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -855,7 +842,7 @@ static int sym53c500_resume(struct pcmcia_device *link)
|
|||||||
static void
|
static void
|
||||||
SYM53C500_detach(struct pcmcia_device *link)
|
SYM53C500_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "SYM53C500_detach\n");
|
||||||
|
|
||||||
SYM53C500_release(link);
|
SYM53C500_release(link);
|
||||||
|
|
||||||
@ -868,7 +855,7 @@ SYM53C500_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct scsi_info_t *info;
|
struct scsi_info_t *info;
|
||||||
|
|
||||||
DEBUG(0, "SYM53C500_attach()\n");
|
dev_dbg(&link->dev, "SYM53C500_attach()\n");
|
||||||
|
|
||||||
/* Create new SCSI device */
|
/* Create new SCSI device */
|
||||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||||
@ -880,7 +867,6 @@ SYM53C500_probe(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
link->io.IOAddrLines = 10;
|
link->io.IOAddrLines = 10;
|
||||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
|
@ -54,14 +54,6 @@
|
|||||||
|
|
||||||
#include "8250.h"
|
#include "8250.h"
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
@ -121,24 +113,20 @@ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_
|
|||||||
static int quirk_post_ibm(struct pcmcia_device *link)
|
static int quirk_post_ibm(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
|
conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
|
||||||
int last_ret, last_fn;
|
int ret;
|
||||||
|
|
||||||
|
ret = pcmcia_access_configuration_register(link, ®);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
|
||||||
if (last_ret) {
|
|
||||||
last_fn = AccessConfigurationRegister;
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
reg.Action = CS_WRITE;
|
reg.Action = CS_WRITE;
|
||||||
reg.Value = reg.Value | 1;
|
reg.Value = reg.Value | 1;
|
||||||
last_ret = pcmcia_access_configuration_register(link, ®);
|
ret = pcmcia_access_configuration_register(link, ®);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
last_fn = AccessConfigurationRegister;
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +271,7 @@ static void serial_remove(struct pcmcia_device *link)
|
|||||||
struct serial_info *info = link->priv;
|
struct serial_info *info = link->priv;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DEBUG(0, "serial_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "serial_release\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recheck to see if the device is still configured.
|
* Recheck to see if the device is still configured.
|
||||||
@ -334,7 +322,7 @@ static int serial_probe(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct serial_info *info;
|
struct serial_info *info;
|
||||||
|
|
||||||
DEBUG(0, "serial_attach()\n");
|
dev_dbg(&link->dev, "serial_attach()\n");
|
||||||
|
|
||||||
/* Create new serial device */
|
/* Create new serial device */
|
||||||
info = kzalloc(sizeof (*info), GFP_KERNEL);
|
info = kzalloc(sizeof (*info), GFP_KERNEL);
|
||||||
@ -346,7 +334,6 @@ static int serial_probe(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
link->io.NumPorts1 = 8;
|
link->io.NumPorts1 = 8;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
if (do_sound) {
|
if (do_sound) {
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
@ -370,7 +357,7 @@ static void serial_detach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct serial_info *info = link->priv;
|
struct serial_info *info = link->priv;
|
||||||
|
|
||||||
DEBUG(0, "serial_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "serial_detach\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure any outstanding scheduled tasks are completed.
|
* Ensure any outstanding scheduled tasks are completed.
|
||||||
@ -399,7 +386,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
|
|||||||
port.irq = irq;
|
port.irq = irq;
|
||||||
port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
|
port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
|
||||||
port.uartclk = 1843200;
|
port.uartclk = 1843200;
|
||||||
port.dev = &handle_to_dev(handle);
|
port.dev = &handle->dev;
|
||||||
if (buggy_uart)
|
if (buggy_uart)
|
||||||
port.flags |= UPF_BUGGY_UART;
|
port.flags |= UPF_BUGGY_UART;
|
||||||
|
|
||||||
@ -426,21 +413,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
|
|||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
static int
|
|
||||||
first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
i = pcmcia_get_first_tuple(handle, tuple);
|
|
||||||
if (i != 0)
|
|
||||||
return i;
|
|
||||||
i = pcmcia_get_tuple_data(handle, tuple);
|
|
||||||
if (i != 0)
|
|
||||||
return i;
|
|
||||||
return pcmcia_parse_tuple(tuple, parse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*====================================================================*/
|
|
||||||
|
|
||||||
static int simple_config_check(struct pcmcia_device *p_dev,
|
static int simple_config_check(struct pcmcia_device *p_dev,
|
||||||
cistpl_cftable_entry_t *cf,
|
cistpl_cftable_entry_t *cf,
|
||||||
cistpl_cftable_entry_t *dflt,
|
cistpl_cftable_entry_t *dflt,
|
||||||
@ -522,15 +494,13 @@ static int simple_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
printk(KERN_NOTICE
|
printk(KERN_NOTICE
|
||||||
"serial_cs: no usable port range found, giving up\n");
|
"serial_cs: no usable port range found, giving up\n");
|
||||||
cs_error(link, RequestIO, i);
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
found_port:
|
found_port:
|
||||||
i = pcmcia_request_irq(link, &link->irq);
|
i = pcmcia_request_irq(link, &link->irq);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
}
|
|
||||||
if (info->multi && (info->manfid == MANFID_3COM))
|
if (info->multi && (info->manfid == MANFID_3COM))
|
||||||
link->conf.ConfigIndex &= ~(0x08);
|
link->conf.ConfigIndex &= ~(0x08);
|
||||||
|
|
||||||
@ -541,10 +511,8 @@ static int simple_config(struct pcmcia_device *link)
|
|||||||
info->quirk->config(link);
|
info->quirk->config(link);
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +581,6 @@ static int multi_config(struct pcmcia_device *link)
|
|||||||
/* FIXME: comment does not fit, error handling does not fit */
|
/* FIXME: comment does not fit, error handling does not fit */
|
||||||
printk(KERN_NOTICE
|
printk(KERN_NOTICE
|
||||||
"serial_cs: no usable port range found, giving up\n");
|
"serial_cs: no usable port range found, giving up\n");
|
||||||
cs_error(link, RequestIRQ, i);
|
|
||||||
link->irq.AssignedIRQ = 0;
|
link->irq.AssignedIRQ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,10 +591,8 @@ static int multi_config(struct pcmcia_device *link)
|
|||||||
info->quirk->config(link);
|
info->quirk->config(link);
|
||||||
|
|
||||||
i = pcmcia_request_configuration(link, &link->conf);
|
i = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (i != 0) {
|
if (i != 0)
|
||||||
cs_error(link, RequestConfiguration, i);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
|
||||||
|
|
||||||
/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
|
/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
|
||||||
* 8 registers are for the UART, the others are extra registers.
|
* 8 registers are for the UART, the others are extra registers.
|
||||||
@ -665,6 +630,25 @@ static int multi_config(struct pcmcia_device *link)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int serial_check_for_multi(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cf,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
struct serial_info *info = p_dev->priv;
|
||||||
|
|
||||||
|
if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
|
||||||
|
info->multi = cf->io.win[0].len >> 3;
|
||||||
|
|
||||||
|
if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
|
||||||
|
(cf->io.win[1].len == 8))
|
||||||
|
info->multi = 2;
|
||||||
|
|
||||||
|
return 0; /* break */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
|
|
||||||
serial_config() is scheduled to run after a CARD_INSERTION event
|
serial_config() is scheduled to run after a CARD_INSERTION event
|
||||||
@ -676,46 +660,14 @@ static int multi_config(struct pcmcia_device *link)
|
|||||||
static int serial_config(struct pcmcia_device * link)
|
static int serial_config(struct pcmcia_device * link)
|
||||||
{
|
{
|
||||||
struct serial_info *info = link->priv;
|
struct serial_info *info = link->priv;
|
||||||
struct serial_cfg_mem *cfg_mem;
|
int i;
|
||||||
tuple_t *tuple;
|
|
||||||
u_char *buf;
|
|
||||||
cisparse_t *parse;
|
|
||||||
cistpl_cftable_entry_t *cf;
|
|
||||||
int i, last_ret, last_fn;
|
|
||||||
|
|
||||||
DEBUG(0, "serial_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "serial_config\n");
|
||||||
|
|
||||||
cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
|
|
||||||
if (!cfg_mem)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
tuple = &cfg_mem->tuple;
|
|
||||||
parse = &cfg_mem->parse;
|
|
||||||
cf = &parse->cftable_entry;
|
|
||||||
buf = cfg_mem->buf;
|
|
||||||
|
|
||||||
tuple->TupleData = (cisdata_t *) buf;
|
|
||||||
tuple->TupleOffset = 0;
|
|
||||||
tuple->TupleDataMax = 255;
|
|
||||||
tuple->Attributes = 0;
|
|
||||||
|
|
||||||
/* Get configuration register information */
|
|
||||||
tuple->DesiredTuple = CISTPL_CONFIG;
|
|
||||||
last_ret = first_tuple(link, tuple, parse);
|
|
||||||
if (last_ret != 0) {
|
|
||||||
last_fn = ParseTuple;
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
link->conf.ConfigBase = parse->config.base;
|
|
||||||
link->conf.Present = parse->config.rmask[0];
|
|
||||||
|
|
||||||
/* Is this a compliant multifunction card? */
|
/* Is this a compliant multifunction card? */
|
||||||
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
|
info->multi = (link->socket->functions > 1);
|
||||||
tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
|
|
||||||
info->multi = (first_tuple(link, tuple, parse) == 0);
|
|
||||||
|
|
||||||
/* Is this a multiport card? */
|
/* Is this a multiport card? */
|
||||||
tuple->DesiredTuple = CISTPL_MANFID;
|
|
||||||
info->manfid = link->manf_id;
|
info->manfid = link->manf_id;
|
||||||
info->prodid = link->card_id;
|
info->prodid = link->card_id;
|
||||||
|
|
||||||
@ -730,20 +682,11 @@ static int serial_config(struct pcmcia_device * link)
|
|||||||
|
|
||||||
/* Another check for dual-serial cards: look for either serial or
|
/* Another check for dual-serial cards: look for either serial or
|
||||||
multifunction cards that ask for appropriate IO port ranges */
|
multifunction cards that ask for appropriate IO port ranges */
|
||||||
tuple->DesiredTuple = CISTPL_FUNCID;
|
|
||||||
if ((info->multi == 0) &&
|
if ((info->multi == 0) &&
|
||||||
(link->has_func_id) &&
|
(link->has_func_id) &&
|
||||||
((link->func_id == CISTPL_FUNCID_MULTI) ||
|
((link->func_id == CISTPL_FUNCID_MULTI) ||
|
||||||
(link->func_id == CISTPL_FUNCID_SERIAL))) {
|
(link->func_id == CISTPL_FUNCID_SERIAL)))
|
||||||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
pcmcia_loop_config(link, serial_check_for_multi, info);
|
||||||
if (first_tuple(link, tuple, parse) == 0) {
|
|
||||||
if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
|
|
||||||
info->multi = cf->io.win[0].len >> 3;
|
|
||||||
if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
|
|
||||||
(cf->io.win[1].len == 8))
|
|
||||||
info->multi = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply any multi-port quirk.
|
* Apply any multi-port quirk.
|
||||||
@ -768,14 +711,10 @@ static int serial_config(struct pcmcia_device * link)
|
|||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
link->dev_node = &info->node[0];
|
link->dev_node = &info->node[0];
|
||||||
kfree(cfg_mem);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cs_failed:
|
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
failed:
|
failed:
|
||||||
serial_remove(link);
|
serial_remove(link);
|
||||||
kfree(cfg_mem);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,136 +617,140 @@ static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
|
static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
|
||||||
struct ssb_init_invariants *iv)
|
tuple_t *tuple,
|
||||||
|
void *priv)
|
||||||
{
|
{
|
||||||
tuple_t tuple;
|
struct ssb_sprom *sprom = priv;
|
||||||
int res;
|
|
||||||
unsigned char buf[32];
|
if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
|
||||||
|
return -EINVAL;
|
||||||
|
if (tuple->TupleDataLen != ETH_ALEN + 2)
|
||||||
|
return -EINVAL;
|
||||||
|
if (tuple->TupleData[1] != ETH_ALEN)
|
||||||
|
return -EINVAL;
|
||||||
|
memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
|
||||||
|
tuple_t *tuple,
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
struct ssb_init_invariants *iv = priv;
|
||||||
struct ssb_sprom *sprom = &iv->sprom;
|
struct ssb_sprom *sprom = &iv->sprom;
|
||||||
struct ssb_boardinfo *bi = &iv->boardinfo;
|
struct ssb_boardinfo *bi = &iv->boardinfo;
|
||||||
const char *error_description;
|
const char *error_description;
|
||||||
|
|
||||||
|
GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
|
||||||
|
switch (tuple->TupleData[0]) {
|
||||||
|
case SSB_PCMCIA_CIS_ID:
|
||||||
|
GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
|
||||||
|
(tuple->TupleDataLen != 7),
|
||||||
|
"id tpl size");
|
||||||
|
bi->vendor = tuple->TupleData[1] |
|
||||||
|
((u16)tuple->TupleData[2] << 8);
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_BOARDREV:
|
||||||
|
GOTO_ERROR_ON(tuple->TupleDataLen != 2,
|
||||||
|
"boardrev tpl size");
|
||||||
|
sprom->board_rev = tuple->TupleData[1];
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_PA:
|
||||||
|
GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
|
||||||
|
(tuple->TupleDataLen != 10),
|
||||||
|
"pa tpl size");
|
||||||
|
sprom->pa0b0 = tuple->TupleData[1] |
|
||||||
|
((u16)tuple->TupleData[2] << 8);
|
||||||
|
sprom->pa0b1 = tuple->TupleData[3] |
|
||||||
|
((u16)tuple->TupleData[4] << 8);
|
||||||
|
sprom->pa0b2 = tuple->TupleData[5] |
|
||||||
|
((u16)tuple->TupleData[6] << 8);
|
||||||
|
sprom->itssi_a = tuple->TupleData[7];
|
||||||
|
sprom->itssi_bg = tuple->TupleData[7];
|
||||||
|
sprom->maxpwr_a = tuple->TupleData[8];
|
||||||
|
sprom->maxpwr_bg = tuple->TupleData[8];
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_OEMNAME:
|
||||||
|
/* We ignore this. */
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_CCODE:
|
||||||
|
GOTO_ERROR_ON(tuple->TupleDataLen != 2,
|
||||||
|
"ccode tpl size");
|
||||||
|
sprom->country_code = tuple->TupleData[1];
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_ANTENNA:
|
||||||
|
GOTO_ERROR_ON(tuple->TupleDataLen != 2,
|
||||||
|
"ant tpl size");
|
||||||
|
sprom->ant_available_a = tuple->TupleData[1];
|
||||||
|
sprom->ant_available_bg = tuple->TupleData[1];
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_ANTGAIN:
|
||||||
|
GOTO_ERROR_ON(tuple->TupleDataLen != 2,
|
||||||
|
"antg tpl size");
|
||||||
|
sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
|
||||||
|
sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
|
||||||
|
sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
|
||||||
|
sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
|
||||||
|
sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
|
||||||
|
sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
|
||||||
|
sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
|
||||||
|
sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_BFLAGS:
|
||||||
|
GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
|
||||||
|
(tuple->TupleDataLen != 5),
|
||||||
|
"bfl tpl size");
|
||||||
|
sprom->boardflags_lo = tuple->TupleData[1] |
|
||||||
|
((u16)tuple->TupleData[2] << 8);
|
||||||
|
break;
|
||||||
|
case SSB_PCMCIA_CIS_LEDS:
|
||||||
|
GOTO_ERROR_ON(tuple->TupleDataLen != 5,
|
||||||
|
"leds tpl size");
|
||||||
|
sprom->gpio0 = tuple->TupleData[1];
|
||||||
|
sprom->gpio1 = tuple->TupleData[2];
|
||||||
|
sprom->gpio2 = tuple->TupleData[3];
|
||||||
|
sprom->gpio3 = tuple->TupleData[4];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -ENOSPC; /* continue with next entry */
|
||||||
|
|
||||||
|
error:
|
||||||
|
ssb_printk(KERN_ERR PFX
|
||||||
|
"PCMCIA: Failed to fetch device invariants: %s\n",
|
||||||
|
error_description);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
|
||||||
|
struct ssb_init_invariants *iv)
|
||||||
|
{
|
||||||
|
struct ssb_sprom *sprom = &iv->sprom;
|
||||||
|
int res;
|
||||||
|
|
||||||
memset(sprom, 0xFF, sizeof(*sprom));
|
memset(sprom, 0xFF, sizeof(*sprom));
|
||||||
sprom->revision = 1;
|
sprom->revision = 1;
|
||||||
sprom->boardflags_lo = 0;
|
sprom->boardflags_lo = 0;
|
||||||
sprom->boardflags_hi = 0;
|
sprom->boardflags_hi = 0;
|
||||||
|
|
||||||
/* First fetch the MAC address. */
|
/* First fetch the MAC address. */
|
||||||
memset(&tuple, 0, sizeof(tuple));
|
res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
|
||||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
ssb_pcmcia_get_mac, sprom);
|
||||||
tuple.TupleData = buf;
|
if (res != 0) {
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
ssb_printk(KERN_ERR PFX
|
||||||
res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
|
"PCMCIA: Failed to fetch MAC address\n");
|
||||||
GOTO_ERROR_ON(res != 0, "MAC first tpl");
|
return -ENODEV;
|
||||||
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
|
|
||||||
GOTO_ERROR_ON(res != 0, "MAC first tpl data");
|
|
||||||
while (1) {
|
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
|
|
||||||
if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
|
|
||||||
break;
|
|
||||||
res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
|
|
||||||
GOTO_ERROR_ON(res != 0, "MAC next tpl");
|
|
||||||
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
|
|
||||||
GOTO_ERROR_ON(res != 0, "MAC next tpl data");
|
|
||||||
}
|
}
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
|
|
||||||
memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
|
|
||||||
|
|
||||||
/* Fetch the vendor specific tuples. */
|
/* Fetch the vendor specific tuples. */
|
||||||
memset(&tuple, 0, sizeof(tuple));
|
res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
|
||||||
tuple.DesiredTuple = SSB_PCMCIA_CIS;
|
ssb_pcmcia_do_get_invariants, sprom);
|
||||||
tuple.TupleData = buf;
|
if ((res == 0) || (res == -ENOSPC))
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
return 0;
|
||||||
res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
|
|
||||||
GOTO_ERROR_ON(res != 0, "VEN first tpl");
|
|
||||||
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
|
|
||||||
GOTO_ERROR_ON(res != 0, "VEN first tpl data");
|
|
||||||
while (1) {
|
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
|
|
||||||
switch (tuple.TupleData[0]) {
|
|
||||||
case SSB_PCMCIA_CIS_ID:
|
|
||||||
GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
|
|
||||||
(tuple.TupleDataLen != 7),
|
|
||||||
"id tpl size");
|
|
||||||
bi->vendor = tuple.TupleData[1] |
|
|
||||||
((u16)tuple.TupleData[2] << 8);
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_BOARDREV:
|
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen != 2,
|
|
||||||
"boardrev tpl size");
|
|
||||||
sprom->board_rev = tuple.TupleData[1];
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_PA:
|
|
||||||
GOTO_ERROR_ON((tuple.TupleDataLen != 9) &&
|
|
||||||
(tuple.TupleDataLen != 10),
|
|
||||||
"pa tpl size");
|
|
||||||
sprom->pa0b0 = tuple.TupleData[1] |
|
|
||||||
((u16)tuple.TupleData[2] << 8);
|
|
||||||
sprom->pa0b1 = tuple.TupleData[3] |
|
|
||||||
((u16)tuple.TupleData[4] << 8);
|
|
||||||
sprom->pa0b2 = tuple.TupleData[5] |
|
|
||||||
((u16)tuple.TupleData[6] << 8);
|
|
||||||
sprom->itssi_a = tuple.TupleData[7];
|
|
||||||
sprom->itssi_bg = tuple.TupleData[7];
|
|
||||||
sprom->maxpwr_a = tuple.TupleData[8];
|
|
||||||
sprom->maxpwr_bg = tuple.TupleData[8];
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_OEMNAME:
|
|
||||||
/* We ignore this. */
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_CCODE:
|
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen != 2,
|
|
||||||
"ccode tpl size");
|
|
||||||
sprom->country_code = tuple.TupleData[1];
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_ANTENNA:
|
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen != 2,
|
|
||||||
"ant tpl size");
|
|
||||||
sprom->ant_available_a = tuple.TupleData[1];
|
|
||||||
sprom->ant_available_bg = tuple.TupleData[1];
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_ANTGAIN:
|
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen != 2,
|
|
||||||
"antg tpl size");
|
|
||||||
sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
|
|
||||||
sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
|
|
||||||
sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
|
|
||||||
sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
|
|
||||||
sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
|
|
||||||
sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
|
|
||||||
sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
|
|
||||||
sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_BFLAGS:
|
|
||||||
GOTO_ERROR_ON((tuple.TupleDataLen != 3) &&
|
|
||||||
(tuple.TupleDataLen != 5),
|
|
||||||
"bfl tpl size");
|
|
||||||
sprom->boardflags_lo = tuple.TupleData[1] |
|
|
||||||
((u16)tuple.TupleData[2] << 8);
|
|
||||||
break;
|
|
||||||
case SSB_PCMCIA_CIS_LEDS:
|
|
||||||
GOTO_ERROR_ON(tuple.TupleDataLen != 5,
|
|
||||||
"leds tpl size");
|
|
||||||
sprom->gpio0 = tuple.TupleData[1];
|
|
||||||
sprom->gpio1 = tuple.TupleData[2];
|
|
||||||
sprom->gpio2 = tuple.TupleData[3];
|
|
||||||
sprom->gpio3 = tuple.TupleData[4];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
|
|
||||||
if (res == -ENOSPC)
|
|
||||||
break;
|
|
||||||
GOTO_ERROR_ON(res != 0, "VEN next tpl");
|
|
||||||
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
|
|
||||||
GOTO_ERROR_ON(res != 0, "VEN next tpl data");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
error:
|
|
||||||
ssb_printk(KERN_ERR PFX
|
ssb_printk(KERN_ERR PFX
|
||||||
"PCMCIA: Failed to fetch device invariants: %s\n",
|
"PCMCIA: Failed to fetch device invariants\n");
|
||||||
error_description);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,37 +141,14 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,
|
|||||||
struct comedi_insn *insn,
|
struct comedi_insn *insn,
|
||||||
unsigned int *data);
|
unsigned int *data);
|
||||||
|
|
||||||
static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
|
|
||||||
{
|
|
||||||
tuple_t tuple;
|
|
||||||
u_short buf[128];
|
|
||||||
int prodid = 0;
|
|
||||||
|
|
||||||
tuple.TupleData = (cisdata_t *) buf;
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
tuple.TupleDataMax = 255;
|
|
||||||
tuple.DesiredTuple = CISTPL_MANFID;
|
|
||||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
|
||||||
if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
|
|
||||||
(pcmcia_get_tuple_data(link, &tuple) == 0)) {
|
|
||||||
prodid = le16_to_cpu(buf[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return prodid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
|
static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
|
||||||
struct pcmcia_device *link)
|
struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
int id;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
id = get_prodid(dev, link);
|
|
||||||
|
|
||||||
for (i = 0; i < n_boards; i++) {
|
for (i = 0; i < n_boards; i++) {
|
||||||
if (das16cs_boards[i].device_id == id) {
|
if (das16cs_boards[i].device_id == link->card_id)
|
||||||
return das16cs_boards + i;
|
return das16cs_boards + i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("unknown board!\n");
|
printk("unknown board!\n");
|
||||||
@ -660,27 +637,8 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
|
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version =
|
|
||||||
"cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
|
||||||
|
|
||||||
static void das16cs_pcmcia_config(struct pcmcia_device *link);
|
static void das16cs_pcmcia_config(struct pcmcia_device *link);
|
||||||
static void das16cs_pcmcia_release(struct pcmcia_device *link);
|
static void das16cs_pcmcia_release(struct pcmcia_device *link);
|
||||||
static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
|
static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
|
||||||
@ -733,7 +691,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct local_info_t *local;
|
struct local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "das16cs_pcmcia_attach()\n");
|
dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
||||||
@ -745,7 +703,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
|
|||||||
/* Initialize the pcmcia_device structure */
|
/* Initialize the pcmcia_device structure */
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
link->conf.Attributes = 0;
|
link->conf.Attributes = 0;
|
||||||
@ -760,7 +717,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void das16cs_pcmcia_detach(struct pcmcia_device *link)
|
static void das16cs_pcmcia_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "das16cs_pcmcia_detach\n");
|
||||||
|
|
||||||
if (link->dev_node) {
|
if (link->dev_node) {
|
||||||
((struct local_info_t *)link->priv)->stop = 1;
|
((struct local_info_t *)link->priv)->stop = 1;
|
||||||
@ -771,118 +728,55 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
|
|||||||
kfree(link->priv);
|
kfree(link->priv);
|
||||||
} /* das16cs_pcmcia_detach */
|
} /* das16cs_pcmcia_detach */
|
||||||
|
|
||||||
|
|
||||||
|
static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
if (cfg->index == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Do we need to allocate an interrupt? */
|
||||||
|
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||||
|
|
||||||
|
/* IO window settings */
|
||||||
|
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||||
|
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||||
|
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
if (!(io->flags & CISTPL_IO_8BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
|
if (!(io->flags & CISTPL_IO_16BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
|
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||||
|
p_dev->io.BasePort1 = io->win[0].base;
|
||||||
|
p_dev->io.NumPorts1 = io->win[0].len;
|
||||||
|
if (io->nwin > 1) {
|
||||||
|
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||||
|
p_dev->io.BasePort2 = io->win[1].base;
|
||||||
|
p_dev->io.NumPorts2 = io->win[1].len;
|
||||||
|
}
|
||||||
|
/* This reserves IO space but doesn't actually enable it */
|
||||||
|
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct local_info_t *dev = link->priv;
|
struct local_info_t *dev = link->priv;
|
||||||
tuple_t tuple;
|
int ret;
|
||||||
cisparse_t parse;
|
|
||||||
int last_fn, last_ret;
|
|
||||||
u_char buf[64];
|
|
||||||
cistpl_cftable_entry_t dflt = { 0 };
|
|
||||||
|
|
||||||
DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "das16cs_pcmcia_config\n");
|
||||||
|
|
||||||
/*
|
ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
|
||||||
This reads the card's CONFIG tuple to find its configuration
|
if (ret) {
|
||||||
registers.
|
dev_warn(&link->dev, "no configuration found\n");
|
||||||
*/
|
goto failed;
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
last_fn = GetFirstTuple;
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret != 0)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
last_fn = GetTupleData;
|
|
||||||
last_ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
if (last_ret != 0)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
last_fn = ParseTuple;
|
|
||||||
last_ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
if (last_ret != 0)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
link->conf.ConfigBase = parse.config.base;
|
|
||||||
link->conf.Present = parse.config.rmask[0];
|
|
||||||
|
|
||||||
/*
|
|
||||||
In this loop, we scan the CIS for configuration table entries,
|
|
||||||
each of which describes a valid card configuration, including
|
|
||||||
voltage, IO window, memory window, and interrupt settings.
|
|
||||||
|
|
||||||
We make no assumptions about the card to be configured: we use
|
|
||||||
just the information available in the CIS. In an ideal world,
|
|
||||||
this would work for any PCMCIA card, but it requires a complete
|
|
||||||
and accurate CIS. In practice, a driver usually "knows" most of
|
|
||||||
these things without consulting the CIS, and most client drivers
|
|
||||||
will only use the CIS to fill in implementation-defined details.
|
|
||||||
*/
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
last_fn = GetFirstTuple;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
|
||||||
if (pcmcia_get_tuple_data(link, &tuple))
|
|
||||||
goto next_entry;
|
|
||||||
if (pcmcia_parse_tuple(&tuple, &parse))
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
|
||||||
dflt = *cfg;
|
|
||||||
if (cfg->index == 0)
|
|
||||||
goto next_entry;
|
|
||||||
link->conf.ConfigIndex = cfg->index;
|
|
||||||
|
|
||||||
/* Does this card need audio output? */
|
|
||||||
/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* Do we need to allocate an interrupt? */
|
|
||||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
|
||||||
|
|
||||||
/* IO window settings */
|
|
||||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
|
||||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
|
||||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
if (!(io->flags & CISTPL_IO_8BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
|
||||||
if (!(io->flags & CISTPL_IO_16BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
|
||||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
|
||||||
link->io.BasePort1 = io->win[0].base;
|
|
||||||
link->io.NumPorts1 = io->win[0].len;
|
|
||||||
if (io->nwin > 1) {
|
|
||||||
link->io.Attributes2 = link->io.Attributes1;
|
|
||||||
link->io.BasePort2 = io->win[1].base;
|
|
||||||
link->io.NumPorts2 = io->win[1].len;
|
|
||||||
}
|
|
||||||
/* This reserves IO space but doesn't actually enable it */
|
|
||||||
if (pcmcia_request_io(link, &link->io))
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we got this far, we're cool! */
|
|
||||||
break;
|
|
||||||
|
|
||||||
next_entry:
|
|
||||||
last_fn = GetNextTuple;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -891,21 +785,18 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
|||||||
irq structure is initialized.
|
irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
last_fn = RequestIRQ;
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
|
if (ret)
|
||||||
last_ret = pcmcia_request_irq(link, &link->irq);
|
goto failed;
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
This actually configures the PCMCIA socket -- setting up
|
This actually configures the PCMCIA socket -- setting up
|
||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
last_fn = RequestConfiguration;
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
last_ret = pcmcia_request_configuration(link, &link->conf);
|
if (ret)
|
||||||
if (last_ret)
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At this point, the dev_node_t structure(s) need to be
|
At this point, the dev_node_t structure(s) need to be
|
||||||
@ -930,14 +821,13 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
das16cs_pcmcia_release(link);
|
das16cs_pcmcia_release(link);
|
||||||
} /* das16cs_pcmcia_config */
|
} /* das16cs_pcmcia_config */
|
||||||
|
|
||||||
static void das16cs_pcmcia_release(struct pcmcia_device *link)
|
static void das16cs_pcmcia_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "das16cs_pcmcia_release\n");
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
} /* das16cs_pcmcia_release */
|
} /* das16cs_pcmcia_release */
|
||||||
|
|
||||||
@ -983,14 +873,13 @@ struct pcmcia_driver das16cs_driver = {
|
|||||||
|
|
||||||
static int __init init_das16cs_pcmcia_cs(void)
|
static int __init init_das16cs_pcmcia_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "%s\n", version);
|
|
||||||
pcmcia_register_driver(&das16cs_driver);
|
pcmcia_register_driver(&das16cs_driver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit exit_das16cs_pcmcia_cs(void)
|
static void __exit exit_das16cs_pcmcia_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
|
pr_debug("das16cs_pcmcia_cs: unloading\n");
|
||||||
pcmcia_unregister_driver(&das16cs_driver);
|
pcmcia_unregister_driver(&das16cs_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,25 +110,6 @@ static int das08_cs_attach(struct comedi_device *dev,
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static const char *version =
|
|
||||||
"das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
|
||||||
static void das08_pcmcia_config(struct pcmcia_device *link);
|
static void das08_pcmcia_config(struct pcmcia_device *link);
|
||||||
static void das08_pcmcia_release(struct pcmcia_device *link);
|
static void das08_pcmcia_release(struct pcmcia_device *link);
|
||||||
static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
|
static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
|
||||||
@ -181,7 +162,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct local_info_t *local;
|
struct local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "das08_pcmcia_attach()\n");
|
dev_dbg(&link->dev, "das08_pcmcia_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
||||||
@ -192,7 +173,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -224,7 +204,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
|
|||||||
static void das08_pcmcia_detach(struct pcmcia_device *link)
|
static void das08_pcmcia_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
|
|
||||||
DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "das08_pcmcia_detach\n");
|
||||||
|
|
||||||
if (link->dev_node) {
|
if (link->dev_node) {
|
||||||
((struct local_info_t *)link->priv)->stop = 1;
|
((struct local_info_t *)link->priv)->stop = 1;
|
||||||
@ -237,6 +217,44 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
} /* das08_pcmcia_detach */
|
} /* das08_pcmcia_detach */
|
||||||
|
|
||||||
|
|
||||||
|
static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
if (cfg->index == 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* Do we need to allocate an interrupt? */
|
||||||
|
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||||
|
|
||||||
|
/* IO window settings */
|
||||||
|
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||||
|
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||||
|
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
if (!(io->flags & CISTPL_IO_8BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
|
if (!(io->flags & CISTPL_IO_16BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
|
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||||
|
p_dev->io.BasePort1 = io->win[0].base;
|
||||||
|
p_dev->io.NumPorts1 = io->win[0].len;
|
||||||
|
if (io->nwin > 1) {
|
||||||
|
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||||
|
p_dev->io.BasePort2 = io->win[1].base;
|
||||||
|
p_dev->io.NumPorts2 = io->win[1].len;
|
||||||
|
}
|
||||||
|
/* This reserves IO space but doesn't actually enable it */
|
||||||
|
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
|
|
||||||
das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
|
das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
|
||||||
@ -248,128 +266,20 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
|
|||||||
static void das08_pcmcia_config(struct pcmcia_device *link)
|
static void das08_pcmcia_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct local_info_t *dev = link->priv;
|
struct local_info_t *dev = link->priv;
|
||||||
tuple_t tuple;
|
int ret;
|
||||||
cisparse_t parse;
|
|
||||||
int last_fn, last_ret;
|
|
||||||
u_char buf[64];
|
|
||||||
cistpl_cftable_entry_t dflt = { 0 };
|
|
||||||
|
|
||||||
DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "das08_pcmcia_config\n");
|
||||||
|
|
||||||
/*
|
ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
|
||||||
This reads the card's CONFIG tuple to find its configuration
|
if (ret) {
|
||||||
registers.
|
dev_warn(&link->dev, "no configuration found\n");
|
||||||
*/
|
goto failed;
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
last_fn = GetFirstTuple;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
last_fn = GetTupleData;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
last_fn = ParseTuple;
|
|
||||||
|
|
||||||
last_ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
link->conf.ConfigBase = parse.config.base;
|
|
||||||
link->conf.Present = parse.config.rmask[0];
|
|
||||||
|
|
||||||
/*
|
|
||||||
In this loop, we scan the CIS for configuration table entries,
|
|
||||||
each of which describes a valid card configuration, including
|
|
||||||
voltage, IO window, memory window, and interrupt settings.
|
|
||||||
|
|
||||||
We make no assumptions about the card to be configured: we use
|
|
||||||
just the information available in the CIS. In an ideal world,
|
|
||||||
this would work for any PCMCIA card, but it requires a complete
|
|
||||||
and accurate CIS. In practice, a driver usually "knows" most of
|
|
||||||
these things without consulting the CIS, and most client drivers
|
|
||||||
will only use the CIS to fill in implementation-defined details.
|
|
||||||
*/
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
last_fn = GetFirstTuple;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
if (last_ret)
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
last_ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
if (last_ret)
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
|
||||||
dflt = *cfg;
|
|
||||||
if (cfg->index == 0)
|
|
||||||
goto next_entry;
|
|
||||||
link->conf.ConfigIndex = cfg->index;
|
|
||||||
|
|
||||||
/* Does this card need audio output? */
|
|
||||||
/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* Do we need to allocate an interrupt? */
|
|
||||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
|
||||||
|
|
||||||
/* IO window settings */
|
|
||||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
|
||||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
|
||||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
if (!(io->flags & CISTPL_IO_8BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
|
||||||
if (!(io->flags & CISTPL_IO_16BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
|
||||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
|
||||||
link->io.BasePort1 = io->win[0].base;
|
|
||||||
link->io.NumPorts1 = io->win[0].len;
|
|
||||||
if (io->nwin > 1) {
|
|
||||||
link->io.Attributes2 = link->io.Attributes1;
|
|
||||||
link->io.BasePort2 = io->win[1].base;
|
|
||||||
link->io.NumPorts2 = io->win[1].len;
|
|
||||||
}
|
|
||||||
/* This reserves IO space but doesn't actually enable it */
|
|
||||||
if (pcmcia_request_io(link, &link->io) != 0)
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we got this far, we're cool! */
|
|
||||||
break;
|
|
||||||
|
|
||||||
next_entry:
|
|
||||||
last_fn = GetNextTuple;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
|
||||||
if (last_ret)
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
last_fn = RequestIRQ;
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
last_ret = pcmcia_request_irq(link, &link->irq);
|
if (ret)
|
||||||
if (last_ret)
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -377,10 +287,9 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
|
|||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
last_fn = RequestConfiguration;
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
last_ret = pcmcia_request_configuration(link, &link->conf);
|
if (ret)
|
||||||
if (last_ret)
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At this point, the dev_node_t structure(s) need to be
|
At this point, the dev_node_t structure(s) need to be
|
||||||
@ -405,8 +314,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
cs_error(link, last_fn, last_ret);
|
|
||||||
das08_pcmcia_release(link);
|
das08_pcmcia_release(link);
|
||||||
|
|
||||||
} /* das08_pcmcia_config */
|
} /* das08_pcmcia_config */
|
||||||
@ -421,7 +329,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void das08_pcmcia_release(struct pcmcia_device *link)
|
static void das08_pcmcia_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "das08_pcmcia_release\n");
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
} /* das08_pcmcia_release */
|
} /* das08_pcmcia_release */
|
||||||
|
|
||||||
@ -477,14 +385,13 @@ struct pcmcia_driver das08_cs_driver = {
|
|||||||
|
|
||||||
static int __init init_das08_pcmcia_cs(void)
|
static int __init init_das08_pcmcia_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "%s\n", version);
|
|
||||||
pcmcia_register_driver(&das08_cs_driver);
|
pcmcia_register_driver(&das08_cs_driver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit exit_das08_pcmcia_cs(void)
|
static void __exit exit_das08_pcmcia_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "das08_pcmcia_cs: unloading\n");
|
pr_debug("das08_pcmcia_cs: unloading\n");
|
||||||
pcmcia_unregister_driver(&das08_cs_driver);
|
pcmcia_unregister_driver(&das08_cs_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,25 +436,7 @@ static int dio700_detach(struct comedi_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PCMCIA crap */
|
/* PCMCIA crap -- watch your words, please! */
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version = "ni_daq_700.c, based on dummy_cs.c";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
|
||||||
|
|
||||||
static void dio700_config(struct pcmcia_device *link);
|
static void dio700_config(struct pcmcia_device *link);
|
||||||
static void dio700_release(struct pcmcia_device *link);
|
static void dio700_release(struct pcmcia_device *link);
|
||||||
@ -510,7 +492,7 @@ static int dio700_cs_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
printk(KERN_INFO "ni_daq_700: cs-attach\n");
|
printk(KERN_INFO "ni_daq_700: cs-attach\n");
|
||||||
|
|
||||||
DEBUG(0, "dio700_cs_attach()\n");
|
dev_dbg(&link->dev, "dio700_cs_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
||||||
@ -521,7 +503,6 @@ static int dio700_cs_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -555,7 +536,7 @@ static void dio700_cs_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
printk(KERN_INFO "ni_daq_700: cs-detach!\n");
|
printk(KERN_INFO "ni_daq_700: cs-detach!\n");
|
||||||
|
|
||||||
DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "dio700_cs_detach\n");
|
||||||
|
|
||||||
if (link->dev_node) {
|
if (link->dev_node) {
|
||||||
((struct local_info_t *)link->priv)->stop = 1;
|
((struct local_info_t *)link->priv)->stop = 1;
|
||||||
@ -576,141 +557,85 @@ static void dio700_cs_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
|
static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
win_req_t *req = priv_data;
|
||||||
|
memreq_t map;
|
||||||
|
|
||||||
|
if (cfg->index == 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* Does this card need audio output? */
|
||||||
|
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
|
p_dev->conf.Status = CCSR_AUDIO_ENA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we need to allocate an interrupt? */
|
||||||
|
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||||
|
|
||||||
|
/* IO window settings */
|
||||||
|
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||||
|
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||||
|
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
if (!(io->flags & CISTPL_IO_8BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
|
if (!(io->flags & CISTPL_IO_16BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
|
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||||
|
p_dev->io.BasePort1 = io->win[0].base;
|
||||||
|
p_dev->io.NumPorts1 = io->win[0].len;
|
||||||
|
if (io->nwin > 1) {
|
||||||
|
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||||
|
p_dev->io.BasePort2 = io->win[1].base;
|
||||||
|
p_dev->io.NumPorts2 = io->win[1].len;
|
||||||
|
}
|
||||||
|
/* This reserves IO space but doesn't actually enable it */
|
||||||
|
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
|
||||||
|
cistpl_mem_t *mem =
|
||||||
|
(cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
|
||||||
|
req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
|
||||||
|
req->Attributes |= WIN_ENABLE;
|
||||||
|
req->Base = mem->win[0].host_addr;
|
||||||
|
req->Size = mem->win[0].len;
|
||||||
|
if (req->Size < 0x1000)
|
||||||
|
req->Size = 0x1000;
|
||||||
|
req->AccessSpeed = 0;
|
||||||
|
if (pcmcia_request_window(p_dev, req, &p_dev->win))
|
||||||
|
return -ENODEV;
|
||||||
|
map.Page = 0;
|
||||||
|
map.CardOffset = mem->win[0].card_addr;
|
||||||
|
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
/* If we got this far, we're cool! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void dio700_config(struct pcmcia_device *link)
|
static void dio700_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct local_info_t *dev = link->priv;
|
struct local_info_t *dev = link->priv;
|
||||||
tuple_t tuple;
|
|
||||||
cisparse_t parse;
|
|
||||||
int last_ret;
|
|
||||||
u_char buf[64];
|
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
memreq_t map;
|
int ret;
|
||||||
cistpl_cftable_entry_t dflt = { 0 };
|
|
||||||
|
|
||||||
printk(KERN_INFO "ni_daq_700: cs-config\n");
|
printk(KERN_INFO "ni_daq_700: cs-config\n");
|
||||||
|
|
||||||
DEBUG(0, "dio700_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "dio700_config\n");
|
||||||
|
|
||||||
/*
|
ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, &req);
|
||||||
This reads the card's CONFIG tuple to find its configuration
|
if (ret) {
|
||||||
registers.
|
dev_warn(&link->dev, "no configuration found\n");
|
||||||
*/
|
goto failed;
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetFirstTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetTupleData, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, ParseTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
link->conf.ConfigBase = parse.config.base;
|
|
||||||
link->conf.Present = parse.config.rmask[0];
|
|
||||||
|
|
||||||
/*
|
|
||||||
In this loop, we scan the CIS for configuration table entries,
|
|
||||||
each of which describes a valid card configuration, including
|
|
||||||
voltage, IO window, memory window, and interrupt settings.
|
|
||||||
|
|
||||||
We make no assumptions about the card to be configured: we use
|
|
||||||
just the information available in the CIS. In an ideal world,
|
|
||||||
this would work for any PCMCIA card, but it requires a complete
|
|
||||||
and accurate CIS. In practice, a driver usually "knows" most of
|
|
||||||
these things without consulting the CIS, and most client drivers
|
|
||||||
will only use the CIS to fill in implementation-defined details.
|
|
||||||
*/
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret != 0) {
|
|
||||||
cs_error(link, GetFirstTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
while (1) {
|
|
||||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
|
||||||
if (pcmcia_get_tuple_data(link, &tuple) != 0)
|
|
||||||
goto next_entry;
|
|
||||||
if (pcmcia_parse_tuple(&tuple, &parse) != 0)
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
|
||||||
dflt = *cfg;
|
|
||||||
if (cfg->index == 0)
|
|
||||||
goto next_entry;
|
|
||||||
link->conf.ConfigIndex = cfg->index;
|
|
||||||
|
|
||||||
/* Does this card need audio output? */
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do we need to allocate an interrupt? */
|
|
||||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
|
||||||
|
|
||||||
/* IO window settings */
|
|
||||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
|
||||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
|
||||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
if (!(io->flags & CISTPL_IO_8BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
|
||||||
if (!(io->flags & CISTPL_IO_16BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
|
||||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
|
||||||
link->io.BasePort1 = io->win[0].base;
|
|
||||||
link->io.NumPorts1 = io->win[0].len;
|
|
||||||
if (io->nwin > 1) {
|
|
||||||
link->io.Attributes2 = link->io.Attributes1;
|
|
||||||
link->io.BasePort2 = io->win[1].base;
|
|
||||||
link->io.NumPorts2 = io->win[1].len;
|
|
||||||
}
|
|
||||||
/* This reserves IO space but doesn't actually enable it */
|
|
||||||
if (pcmcia_request_io(link, &link->io) != 0)
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
|
|
||||||
cistpl_mem_t *mem =
|
|
||||||
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
|
|
||||||
req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
|
|
||||||
req.Attributes |= WIN_ENABLE;
|
|
||||||
req.Base = mem->win[0].host_addr;
|
|
||||||
req.Size = mem->win[0].len;
|
|
||||||
if (req.Size < 0x1000)
|
|
||||||
req.Size = 0x1000;
|
|
||||||
req.AccessSpeed = 0;
|
|
||||||
if (pcmcia_request_window(&link, &req, &link->win))
|
|
||||||
goto next_entry;
|
|
||||||
map.Page = 0;
|
|
||||||
map.CardOffset = mem->win[0].card_addr;
|
|
||||||
if (pcmcia_map_mem_page(link->win, &map))
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
/* If we got this far, we're cool! */
|
|
||||||
break;
|
|
||||||
|
|
||||||
next_entry:
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetNextTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -719,11 +644,9 @@ static void dio700_config(struct pcmcia_device *link)
|
|||||||
irq structure is initialized.
|
irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
last_ret = pcmcia_request_irq(link, &link->irq);
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIRQ, last_ret);
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -731,11 +654,9 @@ static void dio700_config(struct pcmcia_device *link)
|
|||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
last_ret = pcmcia_request_configuration(link, &link->conf);
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (last_ret != 0) {
|
if (ret != 0)
|
||||||
cs_error(link, RequestConfiguration, last_ret);
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At this point, the dev_node_t structure(s) need to be
|
At this point, the dev_node_t structure(s) need to be
|
||||||
@ -763,7 +684,7 @@ static void dio700_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
printk(KERN_INFO "ni_daq_700 cs failed");
|
printk(KERN_INFO "ni_daq_700 cs failed");
|
||||||
dio700_release(link);
|
dio700_release(link);
|
||||||
|
|
||||||
@ -771,7 +692,7 @@ static void dio700_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void dio700_release(struct pcmcia_device *link)
|
static void dio700_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "dio700_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "dio700_release\n");
|
||||||
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
} /* dio700_release */
|
} /* dio700_release */
|
||||||
@ -830,15 +751,13 @@ struct pcmcia_driver dio700_cs_driver = {
|
|||||||
|
|
||||||
static int __init init_dio700_cs(void)
|
static int __init init_dio700_cs(void)
|
||||||
{
|
{
|
||||||
printk("ni_daq_700: cs-init \n");
|
|
||||||
DEBUG(0, "%s\n", version);
|
|
||||||
pcmcia_register_driver(&dio700_cs_driver);
|
pcmcia_register_driver(&dio700_cs_driver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit exit_dio700_cs(void)
|
static void __exit exit_dio700_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "ni_daq_700: unloading\n");
|
pr_debug("ni_daq_700: unloading\n");
|
||||||
pcmcia_unregister_driver(&dio700_cs_driver);
|
pcmcia_unregister_driver(&dio700_cs_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,25 +187,7 @@ static int dio24_detach(struct comedi_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PCMCIA crap */
|
/* PCMCIA crap -- watch your words! */
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
|
||||||
|
|
||||||
static void dio24_config(struct pcmcia_device *link);
|
static void dio24_config(struct pcmcia_device *link);
|
||||||
static void dio24_release(struct pcmcia_device *link);
|
static void dio24_release(struct pcmcia_device *link);
|
||||||
@ -261,7 +243,7 @@ static int dio24_cs_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
|
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
|
||||||
|
|
||||||
DEBUG(0, "dio24_cs_attach()\n");
|
dev_dbg(&link->dev, "dio24_cs_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
||||||
@ -272,7 +254,6 @@ static int dio24_cs_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -306,7 +287,7 @@ static void dio24_cs_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
|
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
|
||||||
|
|
||||||
DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "dio24_cs_detach\n");
|
||||||
|
|
||||||
if (link->dev_node) {
|
if (link->dev_node) {
|
||||||
((struct local_info_t *)link->priv)->stop = 1;
|
((struct local_info_t *)link->priv)->stop = 1;
|
||||||
@ -327,142 +308,85 @@ static void dio24_cs_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
|
static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
win_req_t *req = priv_data;
|
||||||
|
memreq_t map;
|
||||||
|
|
||||||
|
if (cfg->index == 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* Does this card need audio output? */
|
||||||
|
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
|
p_dev->conf.Status = CCSR_AUDIO_ENA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we need to allocate an interrupt? */
|
||||||
|
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||||
|
|
||||||
|
/* IO window settings */
|
||||||
|
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||||
|
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||||
|
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
if (!(io->flags & CISTPL_IO_8BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
|
if (!(io->flags & CISTPL_IO_16BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
|
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||||
|
p_dev->io.BasePort1 = io->win[0].base;
|
||||||
|
p_dev->io.NumPorts1 = io->win[0].len;
|
||||||
|
if (io->nwin > 1) {
|
||||||
|
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||||
|
p_dev->io.BasePort2 = io->win[1].base;
|
||||||
|
p_dev->io.NumPorts2 = io->win[1].len;
|
||||||
|
}
|
||||||
|
/* This reserves IO space but doesn't actually enable it */
|
||||||
|
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
|
||||||
|
cistpl_mem_t *mem =
|
||||||
|
(cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
|
||||||
|
req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
|
||||||
|
req->Attributes |= WIN_ENABLE;
|
||||||
|
req->Base = mem->win[0].host_addr;
|
||||||
|
req->Size = mem->win[0].len;
|
||||||
|
if (req->Size < 0x1000)
|
||||||
|
req->Size = 0x1000;
|
||||||
|
req->AccessSpeed = 0;
|
||||||
|
if (pcmcia_request_window(p_dev, req, &p_dev->win))
|
||||||
|
return -ENODEV;
|
||||||
|
map.Page = 0;
|
||||||
|
map.CardOffset = mem->win[0].card_addr;
|
||||||
|
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
/* If we got this far, we're cool! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void dio24_config(struct pcmcia_device *link)
|
static void dio24_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct local_info_t *dev = link->priv;
|
struct local_info_t *dev = link->priv;
|
||||||
tuple_t tuple;
|
int ret;
|
||||||
cisparse_t parse;
|
|
||||||
int last_ret;
|
|
||||||
u_char buf[64];
|
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
memreq_t map;
|
|
||||||
cistpl_cftable_entry_t dflt = { 0 };
|
|
||||||
|
|
||||||
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
|
printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
|
||||||
|
|
||||||
DEBUG(0, "dio24_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "dio24_config\n");
|
||||||
|
|
||||||
/*
|
ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req);
|
||||||
This reads the card's CONFIG tuple to find its configuration
|
if (ret) {
|
||||||
registers.
|
dev_warn(&link->dev, "no configuration found\n");
|
||||||
*/
|
goto failed;
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetFirstTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetTupleData, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, ParseTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
link->conf.ConfigBase = parse.config.base;
|
|
||||||
link->conf.Present = parse.config.rmask[0];
|
|
||||||
|
|
||||||
/*
|
|
||||||
In this loop, we scan the CIS for configuration table entries,
|
|
||||||
each of which describes a valid card configuration, including
|
|
||||||
voltage, IO window, memory window, and interrupt settings.
|
|
||||||
|
|
||||||
We make no assumptions about the card to be configured: we use
|
|
||||||
just the information available in the CIS. In an ideal world,
|
|
||||||
this would work for any PCMCIA card, but it requires a complete
|
|
||||||
and accurate CIS. In practice, a driver usually "knows" most of
|
|
||||||
these things without consulting the CIS, and most client drivers
|
|
||||||
will only use the CIS to fill in implementation-defined details.
|
|
||||||
*/
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetFirstTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
while (1) {
|
|
||||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
|
||||||
if (pcmcia_get_tuple_data(link, &tuple) != 0)
|
|
||||||
goto next_entry;
|
|
||||||
if (pcmcia_parse_tuple(&tuple, &parse) != 0)
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
|
||||||
dflt = *cfg;
|
|
||||||
if (cfg->index == 0)
|
|
||||||
goto next_entry;
|
|
||||||
link->conf.ConfigIndex = cfg->index;
|
|
||||||
|
|
||||||
/* Does this card need audio output? */
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do we need to allocate an interrupt? */
|
|
||||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
|
||||||
|
|
||||||
/* IO window settings */
|
|
||||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
|
||||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
|
||||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
if (!(io->flags & CISTPL_IO_8BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
|
||||||
if (!(io->flags & CISTPL_IO_16BIT))
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
|
||||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
|
||||||
link->io.BasePort1 = io->win[0].base;
|
|
||||||
link->io.NumPorts1 = io->win[0].len;
|
|
||||||
if (io->nwin > 1) {
|
|
||||||
link->io.Attributes2 = link->io.Attributes1;
|
|
||||||
link->io.BasePort2 = io->win[1].base;
|
|
||||||
link->io.NumPorts2 = io->win[1].len;
|
|
||||||
}
|
|
||||||
/* This reserves IO space but doesn't actually enable it */
|
|
||||||
if (pcmcia_request_io(link, &link->io) != 0)
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
|
|
||||||
cistpl_mem_t *mem =
|
|
||||||
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
|
|
||||||
req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
|
|
||||||
req.Attributes |= WIN_ENABLE;
|
|
||||||
req.Base = mem->win[0].host_addr;
|
|
||||||
req.Size = mem->win[0].len;
|
|
||||||
if (req.Size < 0x1000)
|
|
||||||
req.Size = 0x1000;
|
|
||||||
req.AccessSpeed = 0;
|
|
||||||
if (pcmcia_request_window(&link, &req, &link->win))
|
|
||||||
goto next_entry;
|
|
||||||
map.Page = 0;
|
|
||||||
map.CardOffset = mem->win[0].card_addr;
|
|
||||||
if (pcmcia_map_mem_page(link->win, &map))
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
/* If we got this far, we're cool! */
|
|
||||||
break;
|
|
||||||
|
|
||||||
next_entry:
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetNextTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -471,11 +395,9 @@ static void dio24_config(struct pcmcia_device *link)
|
|||||||
irq structure is initialized.
|
irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
last_ret = pcmcia_request_irq(link, &link->irq);
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIRQ, last_ret);
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -483,11 +405,9 @@ static void dio24_config(struct pcmcia_device *link)
|
|||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
last_ret = pcmcia_request_configuration(link, &link->conf);
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestConfiguration, last_ret);
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At this point, the dev_node_t structure(s) need to be
|
At this point, the dev_node_t structure(s) need to be
|
||||||
@ -515,7 +435,7 @@ static void dio24_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
printk(KERN_INFO "Fallo");
|
printk(KERN_INFO "Fallo");
|
||||||
dio24_release(link);
|
dio24_release(link);
|
||||||
|
|
||||||
@ -523,7 +443,7 @@ static void dio24_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void dio24_release(struct pcmcia_device *link)
|
static void dio24_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "dio24_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "dio24_release\n");
|
||||||
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
} /* dio24_release */
|
} /* dio24_release */
|
||||||
@ -582,14 +502,12 @@ struct pcmcia_driver dio24_cs_driver = {
|
|||||||
static int __init init_dio24_cs(void)
|
static int __init init_dio24_cs(void)
|
||||||
{
|
{
|
||||||
printk("ni_daq_dio24: HOLA SOY YO!\n");
|
printk("ni_daq_dio24: HOLA SOY YO!\n");
|
||||||
DEBUG(0, "%s\n", version);
|
|
||||||
pcmcia_register_driver(&dio24_cs_driver);
|
pcmcia_register_driver(&dio24_cs_driver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit exit_dio24_cs(void)
|
static void __exit exit_dio24_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "ni_dio24: unloading\n");
|
|
||||||
pcmcia_unregister_driver(&dio24_cs_driver);
|
pcmcia_unregister_driver(&dio24_cs_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,23 +153,6 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||||||
return labpc_common_attach(dev, iobase, irq, 0);
|
return labpc_common_attach(dev, iobase, irq, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
|
||||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
|
||||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
|
||||||
be present but disabled -- but it can then be enabled for specific
|
|
||||||
modules at load time with a 'pc_debug=#' option to insmod.
|
|
||||||
*/
|
|
||||||
#ifdef PCMCIA_DEBUG
|
|
||||||
static int pc_debug = PCMCIA_DEBUG;
|
|
||||||
module_param(pc_debug, int, 0644);
|
|
||||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
|
||||||
static const char *version =
|
|
||||||
"ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13";
|
|
||||||
#else
|
|
||||||
#define DEBUG(n, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -236,7 +219,7 @@ static int labpc_cs_attach(struct pcmcia_device *link)
|
|||||||
{
|
{
|
||||||
struct local_info_t *local;
|
struct local_info_t *local;
|
||||||
|
|
||||||
DEBUG(0, "labpc_cs_attach()\n");
|
dev_dbg(&link->dev, "labpc_cs_attach()\n");
|
||||||
|
|
||||||
/* Allocate space for private device-specific data */
|
/* Allocate space for private device-specific data */
|
||||||
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
|
||||||
@ -247,7 +230,6 @@ static int labpc_cs_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
/* Interrupt setup */
|
/* Interrupt setup */
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE;
|
||||||
link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
|
|
||||||
link->irq.Handler = NULL;
|
link->irq.Handler = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -278,7 +260,7 @@ static int labpc_cs_attach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
static void labpc_cs_detach(struct pcmcia_device *link)
|
static void labpc_cs_detach(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "labpc_cs_detach(0x%p)\n", link);
|
dev_dbg(&link->dev, "labpc_cs_detach\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the device is currently configured and active, we won't
|
If the device is currently configured and active, we won't
|
||||||
@ -305,135 +287,84 @@ static void labpc_cs_detach(struct pcmcia_device *link)
|
|||||||
|
|
||||||
======================================================================*/
|
======================================================================*/
|
||||||
|
|
||||||
|
static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
win_req_t *req = priv_data;
|
||||||
|
memreq_t map;
|
||||||
|
|
||||||
|
if (cfg->index == 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* Does this card need audio output? */
|
||||||
|
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||||
|
p_dev->conf.Status = CCSR_AUDIO_ENA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we need to allocate an interrupt? */
|
||||||
|
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||||
|
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||||
|
|
||||||
|
/* IO window settings */
|
||||||
|
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||||
|
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||||
|
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||||
|
if (!(io->flags & CISTPL_IO_8BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
|
if (!(io->flags & CISTPL_IO_16BIT))
|
||||||
|
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||||
|
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||||
|
p_dev->io.BasePort1 = io->win[0].base;
|
||||||
|
p_dev->io.NumPorts1 = io->win[0].len;
|
||||||
|
if (io->nwin > 1) {
|
||||||
|
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||||
|
p_dev->io.BasePort2 = io->win[1].base;
|
||||||
|
p_dev->io.NumPorts2 = io->win[1].len;
|
||||||
|
}
|
||||||
|
/* This reserves IO space but doesn't actually enable it */
|
||||||
|
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
|
||||||
|
cistpl_mem_t *mem =
|
||||||
|
(cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
|
||||||
|
req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
|
||||||
|
req->Attributes |= WIN_ENABLE;
|
||||||
|
req->Base = mem->win[0].host_addr;
|
||||||
|
req->Size = mem->win[0].len;
|
||||||
|
if (req->Size < 0x1000)
|
||||||
|
req->Size = 0x1000;
|
||||||
|
req->AccessSpeed = 0;
|
||||||
|
if (pcmcia_request_window(p_dev, req, &p_dev->win))
|
||||||
|
return -ENODEV;
|
||||||
|
map.Page = 0;
|
||||||
|
map.CardOffset = mem->win[0].card_addr;
|
||||||
|
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
/* If we got this far, we're cool! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void labpc_config(struct pcmcia_device *link)
|
static void labpc_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
struct local_info_t *dev = link->priv;
|
struct local_info_t *dev = link->priv;
|
||||||
tuple_t tuple;
|
int ret;
|
||||||
cisparse_t parse;
|
|
||||||
int last_ret;
|
|
||||||
u_char buf[64];
|
|
||||||
win_req_t req;
|
win_req_t req;
|
||||||
memreq_t map;
|
|
||||||
cistpl_cftable_entry_t dflt = { 0 };
|
|
||||||
|
|
||||||
DEBUG(0, "labpc_config(0x%p)\n", link);
|
dev_dbg(&link->dev, "labpc_config\n");
|
||||||
|
|
||||||
/*
|
ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, &req);
|
||||||
This reads the card's CONFIG tuple to find its configuration
|
if (ret) {
|
||||||
registers.
|
dev_warn(&link->dev, "no configuration found\n");
|
||||||
*/
|
goto failed;
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
tuple.TupleData = buf;
|
|
||||||
tuple.TupleDataMax = sizeof(buf);
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetFirstTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetTupleData, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, ParseTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
link->conf.ConfigBase = parse.config.base;
|
|
||||||
link->conf.Present = parse.config.rmask[0];
|
|
||||||
|
|
||||||
/*
|
|
||||||
In this loop, we scan the CIS for configuration table entries,
|
|
||||||
each of which describes a valid card configuration, including
|
|
||||||
voltage, IO window, memory window, and interrupt settings.
|
|
||||||
|
|
||||||
We make no assumptions about the card to be configured: we use
|
|
||||||
just the information available in the CIS. In an ideal world,
|
|
||||||
this would work for any PCMCIA card, but it requires a complete
|
|
||||||
and accurate CIS. In practice, a driver usually "knows" most of
|
|
||||||
these things without consulting the CIS, and most client drivers
|
|
||||||
will only use the CIS to fill in implementation-defined details.
|
|
||||||
*/
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
last_ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetFirstTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
while (1) {
|
|
||||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
|
||||||
if (pcmcia_get_tuple_data(link, &tuple))
|
|
||||||
goto next_entry;
|
|
||||||
if (pcmcia_parse_tuple(&tuple, &parse))
|
|
||||||
goto next_entry;
|
|
||||||
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
|
||||||
dflt = *cfg;
|
|
||||||
if (cfg->index == 0)
|
|
||||||
goto next_entry;
|
|
||||||
link->conf.ConfigIndex = cfg->index;
|
|
||||||
|
|
||||||
/* Does this card need audio output? */
|
|
||||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
|
||||||
link->conf.Status = CCSR_AUDIO_ENA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do we need to allocate an interrupt? */
|
|
||||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
|
||||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
|
||||||
|
|
||||||
/* IO window settings */
|
|
||||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
|
||||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
|
||||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
|
||||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
|
||||||
link->io.BasePort1 = io->win[0].base;
|
|
||||||
link->io.NumPorts1 = io->win[0].len;
|
|
||||||
if (io->nwin > 1) {
|
|
||||||
link->io.Attributes2 = link->io.Attributes1;
|
|
||||||
link->io.BasePort2 = io->win[1].base;
|
|
||||||
link->io.NumPorts2 = io->win[1].len;
|
|
||||||
}
|
|
||||||
/* This reserves IO space but doesn't actually enable it */
|
|
||||||
if (pcmcia_request_io(link, &link->io))
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
|
|
||||||
cistpl_mem_t *mem =
|
|
||||||
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
|
|
||||||
req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
|
|
||||||
req.Attributes |= WIN_ENABLE;
|
|
||||||
req.Base = mem->win[0].host_addr;
|
|
||||||
req.Size = mem->win[0].len;
|
|
||||||
if (req.Size < 0x1000)
|
|
||||||
req.Size = 0x1000;
|
|
||||||
req.AccessSpeed = 0;
|
|
||||||
link->win = (window_handle_t) link;
|
|
||||||
if (pcmcia_request_window(&link, &req, &link->win))
|
|
||||||
goto next_entry;
|
|
||||||
map.Page = 0;
|
|
||||||
map.CardOffset = mem->win[0].card_addr;
|
|
||||||
if (pcmcia_map_mem_page(link->win, &map))
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
/* If we got this far, we're cool! */
|
|
||||||
break;
|
|
||||||
|
|
||||||
next_entry:
|
|
||||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
|
||||||
if (last_ret) {
|
|
||||||
cs_error(link, GetNextTuple, last_ret);
|
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -442,11 +373,9 @@ static void labpc_config(struct pcmcia_device *link)
|
|||||||
irq structure is initialized.
|
irq structure is initialized.
|
||||||
*/
|
*/
|
||||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||||
last_ret = pcmcia_request_irq(link, &link->irq);
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestIRQ, last_ret);
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -454,11 +383,9 @@ static void labpc_config(struct pcmcia_device *link)
|
|||||||
the I/O windows and the interrupt mapping, and putting the
|
the I/O windows and the interrupt mapping, and putting the
|
||||||
card and host interface into "Memory and IO" mode.
|
card and host interface into "Memory and IO" mode.
|
||||||
*/
|
*/
|
||||||
last_ret = pcmcia_request_configuration(link, &link->conf);
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
if (last_ret) {
|
if (ret)
|
||||||
cs_error(link, RequestConfiguration, last_ret);
|
goto failed;
|
||||||
goto cs_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At this point, the dev_node_t structure(s) need to be
|
At this point, the dev_node_t structure(s) need to be
|
||||||
@ -486,14 +413,14 @@ static void labpc_config(struct pcmcia_device *link)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cs_failed:
|
failed:
|
||||||
labpc_release(link);
|
labpc_release(link);
|
||||||
|
|
||||||
} /* labpc_config */
|
} /* labpc_config */
|
||||||
|
|
||||||
static void labpc_release(struct pcmcia_device *link)
|
static void labpc_release(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
DEBUG(0, "labpc_release(0x%p)\n", link);
|
dev_dbg(&link->dev, "labpc_release\n");
|
||||||
|
|
||||||
pcmcia_disable_device(link);
|
pcmcia_disable_device(link);
|
||||||
} /* labpc_release */
|
} /* labpc_release */
|
||||||
@ -551,14 +478,12 @@ struct pcmcia_driver labpc_cs_driver = {
|
|||||||
|
|
||||||
static int __init init_labpc_cs(void)
|
static int __init init_labpc_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "%s\n", version);
|
|
||||||
pcmcia_register_driver(&labpc_cs_driver);
|
pcmcia_register_driver(&labpc_cs_driver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit exit_labpc_cs(void)
|
static void __exit exit_labpc_cs(void)
|
||||||
{
|
{
|
||||||
DEBUG(0, "ni_labpc: unloading\n");
|
|
||||||
pcmcia_unregister_driver(&labpc_cs_driver);
|
pcmcia_unregister_driver(&labpc_cs_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,6 @@ static int cs_attach(struct pcmcia_device *link)
|
|||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||||
link->io.NumPorts1 = 16;
|
link->io.NumPorts1 = 16;
|
||||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
|
||||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
@ -312,96 +311,47 @@ static int mio_cs_resume(struct pcmcia_device *link)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev,
|
||||||
|
cistpl_cftable_entry_t *cfg,
|
||||||
|
cistpl_cftable_entry_t *dflt,
|
||||||
|
unsigned int vcc,
|
||||||
|
void *priv_data)
|
||||||
|
{
|
||||||
|
int base, ret;
|
||||||
|
|
||||||
|
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||||
|
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
|
||||||
|
p_dev->io.NumPorts2 = 0;
|
||||||
|
|
||||||
|
for (base = 0x000; base < 0x400; base += 0x20) {
|
||||||
|
p_dev->io.BasePort1 = base;
|
||||||
|
ret = pcmcia_request_io(p_dev, &p_dev->io);
|
||||||
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void mio_cs_config(struct pcmcia_device *link)
|
static void mio_cs_config(struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
tuple_t tuple;
|
|
||||||
u_short buf[128];
|
|
||||||
cisparse_t parse;
|
|
||||||
int manfid = 0, prodid = 0;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DPRINTK("mio_cs_config(link=%p)\n", link);
|
DPRINTK("mio_cs_config(link=%p)\n", link);
|
||||||
|
|
||||||
tuple.TupleData = (cisdata_t *) buf;
|
ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL);
|
||||||
tuple.TupleOffset = 0;
|
if (ret) {
|
||||||
tuple.TupleDataMax = 255;
|
dev_warn(&link->dev, "no configuration found\n");
|
||||||
tuple.Attributes = 0;
|
return;
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
|
||||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
link->conf.ConfigBase = parse.config.base;
|
|
||||||
link->conf.Present = parse.config.rmask[0];
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
|
|
||||||
tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
|
|
||||||
info->multi(first_tuple(link, &tuple, &parse) == 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_MANFID;
|
|
||||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
|
||||||
if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
|
|
||||||
(pcmcia_get_tuple_data(link, &tuple) == 0)) {
|
|
||||||
manfid = le16_to_cpu(buf[0]);
|
|
||||||
prodid = le16_to_cpu(buf[1]);
|
|
||||||
}
|
|
||||||
/* printk("manfid = 0x%04x, 0x%04x\n",manfid,prodid); */
|
|
||||||
|
|
||||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
|
||||||
tuple.Attributes = 0;
|
|
||||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
|
||||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
|
||||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
printk(" index: 0x%x\n", parse.cftable_entry.index);
|
|
||||||
printk(" flags: 0x%x\n", parse.cftable_entry.flags);
|
|
||||||
printk(" io flags: 0x%x\n", parse.cftable_entry.io.flags);
|
|
||||||
printk(" io nwin: 0x%x\n", parse.cftable_entry.io.nwin);
|
|
||||||
printk(" io base: 0x%x\n", parse.cftable_entry.io.win[0].base);
|
|
||||||
printk(" io len: 0x%x\n", parse.cftable_entry.io.win[0].len);
|
|
||||||
printk(" irq1: 0x%x\n", parse.cftable_entry.irq.IRQInfo1);
|
|
||||||
printk(" irq2: 0x%x\n", parse.cftable_entry.irq.IRQInfo2);
|
|
||||||
printk(" mem flags: 0x%x\n", parse.cftable_entry.mem.flags);
|
|
||||||
printk(" mem nwin: 0x%x\n", parse.cftable_entry.mem.nwin);
|
|
||||||
printk(" subtuples: 0x%x\n", parse.cftable_entry.subtuples);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
link->io.NumPorts1 = 0x20;
|
|
||||||
link->io.IOAddrLines = 5;
|
|
||||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
|
||||||
#endif
|
|
||||||
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
|
|
||||||
link->io.IOAddrLines =
|
|
||||||
parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
|
|
||||||
link->io.NumPorts2 = 0;
|
|
||||||
|
|
||||||
{
|
|
||||||
int base;
|
|
||||||
for (base = 0x000; base < 0x400; base += 0x20) {
|
|
||||||
link->io.BasePort1 = base;
|
|
||||||
ret = pcmcia_request_io(link, &link->io);
|
|
||||||
/* printk("RequestIO 0x%02x\n",ret); */
|
|
||||||
if (!ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
|
|
||||||
link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2;
|
|
||||||
ret = pcmcia_request_irq(link, &link->irq);
|
ret = pcmcia_request_irq(link, &link->irq);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk("pcmcia_request_irq() returned error: %i\n", ret);
|
printk("pcmcia_request_irq() returned error: %i\n", ret);
|
||||||
}
|
}
|
||||||
/* printk("RequestIRQ 0x%02x\n",ret); */
|
|
||||||
|
|
||||||
link->conf.ConfigIndex = 1;
|
|
||||||
|
|
||||||
ret = pcmcia_request_configuration(link, &link->conf);
|
ret = pcmcia_request_configuration(link, &link->conf);
|
||||||
/* printk("RequestConfiguration %d\n",ret); */
|
|
||||||
|
|
||||||
link->dev_node = &dev_node;
|
link->dev_node = &dev_node;
|
||||||
}
|
}
|
||||||
@ -475,40 +425,17 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
|
|
||||||
{
|
|
||||||
tuple_t tuple;
|
|
||||||
u_short buf[128];
|
|
||||||
int prodid = 0;
|
|
||||||
|
|
||||||
tuple.TupleData = (cisdata_t *) buf;
|
|
||||||
tuple.TupleOffset = 0;
|
|
||||||
tuple.TupleDataMax = 255;
|
|
||||||
tuple.DesiredTuple = CISTPL_MANFID;
|
|
||||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
|
||||||
if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
|
|
||||||
(pcmcia_get_tuple_data(link, &tuple) == 0)) {
|
|
||||||
prodid = le16_to_cpu(buf[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return prodid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ni_getboardtype(struct comedi_device *dev,
|
static int ni_getboardtype(struct comedi_device *dev,
|
||||||
struct pcmcia_device *link)
|
struct pcmcia_device *link)
|
||||||
{
|
{
|
||||||
int id;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
id = get_prodid(dev, link);
|
|
||||||
|
|
||||||
for (i = 0; i < n_ni_boards; i++) {
|
for (i = 0; i < n_ni_boards; i++) {
|
||||||
if (ni_boards[i].device_id == id) {
|
if (ni_boards[i].device_id == link->card_id)
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printk("unknown board 0x%04x -- pretend it is a ", id);
|
printk("unknown board 0x%04x -- pretend it is a ", link->card_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user