diff --git a/[refs] b/[refs] index f14379ab2f75..4676dc9dc2a3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 83fdbfbfe6e7e8906e3a3f8f6bc074d887e92109 +refs/heads/master: 7e71c55ee73988d0cb61045660b899eaac23bf8f diff --git a/trunk/Documentation/dontdiff b/trunk/Documentation/dontdiff index e151b2a36267..e1efc400bed6 100644 --- a/trunk/Documentation/dontdiff +++ b/trunk/Documentation/dontdiff @@ -65,7 +65,6 @@ aicdb.h* asm-offsets.h asm_offsets.h autoconf.h* -av_permissions.h bbootsect bin2c binkernel.spec @@ -96,14 +95,12 @@ docproc elf2ecoff elfconfig.h* fixdep -flask.h fore200e_mkfirm fore200e_pca_fw.c* gconf gen-devlist gen_crc32table gen_init_cpio -genheaders genksyms *_gray256.c ihex2fw diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 332fe3b47e0c..9107b387e91f 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -85,6 +85,7 @@ parameter is applicable: PPT Parallel port support is enabled. PS2 Appropriate PS/2 support is enabled. RAM RAM disk support is enabled. + ROOTPLUG The example Root Plug LSM is enabled. S390 S390 architecture is enabled. SCSI Appropriate SCSI support is enabled. A lot of drivers has their options described inside of @@ -2163,6 +2164,15 @@ and is between 256 and 4096 characters. It is defined in the file Useful for devices that are detected asynchronously (e.g. USB and MMC devices). + root_plug.vendor_id= + [ROOTPLUG] Override the default vendor ID + + root_plug.product_id= + [ROOTPLUG] Override the default product ID + + root_plug.debug= + [ROOTPLUG] Enable debugging output + rw [KNL] Mount root device read-write on boot S [KNL] Run init in single mode diff --git a/trunk/Documentation/pcmcia/driver-changes.txt b/trunk/Documentation/pcmcia/driver-changes.txt index 446f43b309df..059934363caf 100644 --- a/trunk/Documentation/pcmcia/driver-changes.txt +++ b/trunk/Documentation/pcmcia/driver-changes.txt @@ -1,17 +1,5 @@ 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) By calling pcmcia_loop_config(), a driver can iterate over all available configuration options. During a driver's probe() phase, one doesn't need diff --git a/trunk/arch/avr32/include/asm/bug.h b/trunk/arch/avr32/include/asm/bug.h index 2aa373cc61b5..331d45bab18f 100644 --- a/trunk/arch/avr32/include/asm/bug.h +++ b/trunk/arch/avr32/include/asm/bug.h @@ -52,7 +52,7 @@ #define BUG() \ do { \ _BUG_OR_WARN(0); \ - unreachable(); \ + for (;;); \ } while (0) #define WARN_ON(condition) \ diff --git a/trunk/arch/mips/include/asm/bug.h b/trunk/arch/mips/include/asm/bug.h index 540c98a810d1..6cf29c26e873 100644 --- a/trunk/arch/mips/include/asm/bug.h +++ b/trunk/arch/mips/include/asm/bug.h @@ -11,7 +11,9 @@ static inline void __noreturn BUG(void) { __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); - unreachable(); + /* Fool GCC into thinking the function doesn't return. */ + while (1) + ; } #define HAVE_ARCH_BUG diff --git a/trunk/arch/s390/include/asm/bug.h b/trunk/arch/s390/include/asm/bug.h index efb74fd5156e..7efd0abe8887 100644 --- a/trunk/arch/s390/include/asm/bug.h +++ b/trunk/arch/s390/include/asm/bug.h @@ -49,7 +49,7 @@ #define BUG() do { \ __EMIT_BUG(0); \ - unreachable(); \ + for (;;); \ } while (0) #define WARN_ON(x) ({ \ diff --git a/trunk/arch/x86/include/asm/bug.h b/trunk/arch/x86/include/asm/bug.h index f654d1bb17fb..d9cf1cd156d2 100644 --- a/trunk/arch/x86/include/asm/bug.h +++ b/trunk/arch/x86/include/asm/bug.h @@ -22,14 +22,14 @@ do { \ ".popsection" \ : : "i" (__FILE__), "i" (__LINE__), \ "i" (sizeof(struct bug_entry))); \ - unreachable(); \ + for (;;) ; \ } while (0) #else #define BUG() \ do { \ asm volatile("ud2"); \ - unreachable(); \ + for (;;) ; \ } while (0) #endif diff --git a/trunk/drivers/ata/pata_pcmcia.c b/trunk/drivers/ata/pata_pcmcia.c index 1b392c9e8531..dc99e26f8e5b 100644 --- a/trunk/drivers/ata/pata_pcmcia.c +++ b/trunk/drivers/ata/pata_pcmcia.c @@ -177,6 +177,9 @@ static struct ata_port_operations pcmcia_8bit_port_ops = { .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 { unsigned long ctl_base; @@ -249,7 +252,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) struct ata_port *ap; struct ata_pcmcia_info *info; struct pcmcia_config_check *stk = NULL; - int is_kme = 0, ret = -ENOMEM, p; + int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p; unsigned long io_base, ctl_base; void __iomem *io_addr, *ctl_addr; int n_ports = 1; @@ -268,6 +271,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; pdev->io.IOAddrLines = 3; pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + pdev->irq.IRQInfo1 = IRQ_LEVEL_ID; pdev->conf.Attributes = CONF_ENABLE_IRQ; pdev->conf.IntType = INT_MEMORY_AND_IO; @@ -292,13 +296,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) } io_base = pdev->io.BasePort1; ctl_base = stk->ctl_base; - ret = pcmcia_request_irq(pdev, &pdev->irq); - if (ret) - goto failed; - - ret = pcmcia_request_configuration(pdev, &pdev->conf); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf)); /* iomap */ ret = -ENOMEM; @@ -352,6 +351,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) kfree(stk); return 0; +cs_failed: + cs_error(pdev, last_fn, last_ret); failed: kfree(stk); info->ndev = 0; diff --git a/trunk/drivers/bluetooth/bluecard_cs.c b/trunk/drivers/bluetooth/bluecard_cs.c index 2acdc605cb4b..b0e569ba730d 100644 --- a/trunk/drivers/bluetooth/bluecard_cs.c +++ b/trunk/drivers/bluetooth/bluecard_cs.c @@ -867,9 +867,11 @@ static int bluecard_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - 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 = bluecard_interrupt; + link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -903,16 +905,22 @@ static int bluecard_config(struct pcmcia_device *link) break; } - if (i != 0) + if (i != 0) { + cs_error(link, RequestIO, i); goto failed; + } i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + if (i != 0) { + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; + } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if (i != 0) { + cs_error(link, RequestConfiguration, i); goto failed; + } if (bluecard_open(info) != 0) goto failed; diff --git a/trunk/drivers/bluetooth/bt3c_cs.c b/trunk/drivers/bluetooth/bt3c_cs.c index d814a2755ccb..d58e22b9f06a 100644 --- a/trunk/drivers/bluetooth/bt3c_cs.c +++ b/trunk/drivers/bluetooth/bt3c_cs.c @@ -659,9 +659,11 @@ static int bt3c_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - 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 = bt3c_interrupt; + link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -738,16 +740,21 @@ static int bt3c_config(struct pcmcia_device *link) goto found_port; BT_ERR("No usable port range found"); + cs_error(link, RequestIO, -ENODEV); goto failed; found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + if (i != 0) { + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; + } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if (i != 0) { + cs_error(link, RequestConfiguration, i); goto failed; + } if (bt3c_open(info) != 0) goto failed; diff --git a/trunk/drivers/bluetooth/btuart_cs.c b/trunk/drivers/bluetooth/btuart_cs.c index d339464dc15e..efd689a062eb 100644 --- a/trunk/drivers/bluetooth/btuart_cs.c +++ b/trunk/drivers/bluetooth/btuart_cs.c @@ -588,9 +588,11 @@ static int btuart_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - 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 = btuart_interrupt; + link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -667,16 +669,21 @@ static int btuart_config(struct pcmcia_device *link) goto found_port; BT_ERR("No usable port range found"); + cs_error(link, RequestIO, -ENODEV); goto failed; found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + if (i != 0) { + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; + } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if (i != 0) { + cs_error(link, RequestConfiguration, i); goto failed; + } if (btuart_open(info) != 0) goto failed; diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index 4f02a6f3c980..b881a9cd8741 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -573,9 +573,11 @@ static int dtl1_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; - 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 = dtl1_interrupt; + link->irq.Instance = info; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -620,12 +622,16 @@ static int dtl1_config(struct pcmcia_device *link) goto failed; i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + if (i != 0) { + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; + } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if (i != 0) { + cs_error(link, RequestConfiguration, i); goto failed; + } if (dtl1_open(info) != 0) goto failed; diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c index 2db4c0a29b05..c250a31efa53 100644 --- a/trunk/drivers/char/pcmcia/cm4000_cs.c +++ b/trunk/drivers/char/pcmcia/cm4000_cs.c @@ -23,6 +23,8 @@ * All rights reserved. Licensed under dual BSD/GPL license. */ +/* #define PCMCIA_DEBUG 6 */ + #include #include #include @@ -45,17 +47,18 @@ /* #define ATR_CSUM */ -#define reader_to_dev(x) (&x->p_dev->dev) - -/* n (debug level) is ignored */ -/* additional debug output may be enabled by re-compiling with - * CM4000_DEBUG set */ -/* #define CM4000_DEBUG */ -#define DEBUGP(n, rdr, x, args...) do { \ - dev_dbg(reader_to_dev(rdr), "%s:" x, \ - __func__ , ## args); \ +#ifdef PCMCIA_DEBUG +#define reader_to_dev(x) (&handle_to_dev(x->p_dev)) +static int pc_debug = PCMCIA_DEBUG; +module_param(pc_debug, int, 0600); +#define DEBUGP(n, rdr, x, args...) do { \ + if (pc_debug >= (n)) \ + dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ + __func__ , ## args); \ } 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"; #define T_1SEC (HZ) @@ -171,13 +174,14 @@ static unsigned char fi_di_table[10][14] = { /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9} }; -#ifndef CM4000_DEBUG +#ifndef PCMCIA_DEBUG #define xoutb outb #define xinb inb #else static inline void xoutb(unsigned char val, unsigned short port) { - pr_debug("outb(val=%.2x,port=%.4x)\n", val, port); + if (pc_debug >= 7) + printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); outb(val, port); } static inline unsigned char xinb(unsigned short port) @@ -185,7 +189,8 @@ static inline unsigned char xinb(unsigned short port) unsigned char val; val = inb(port); - pr_debug("%.2x=inb(%.4x)\n", val, port); + if (pc_debug >= 7) + printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); return val; } @@ -509,10 +514,12 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) for (i = 0; i < 4; i++) { xoutb(i, REG_BUF_ADDR(iobase)); xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */ -#ifdef CM4000_DEBUG - pr_debug("0x%.2x ", dev->pts[i]); +#ifdef PCMCIA_DEBUG + if (pc_debug >= 5) + printk("0x%.2x ", dev->pts[i]); } - pr_debug("\n"); + if (pc_debug >= 5) + printk("\n"); #else } #endif @@ -572,13 +579,14 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) pts_reply[i] = inb(REG_BUF_DATA(iobase)); } -#ifdef CM4000_DEBUG +#ifdef PCMCIA_DEBUG DEBUGP(2, dev, "PTSreply: "); for (i = 0; i < num_bytes_read; i++) { - pr_debug("0x%.2x ", pts_reply[i]); + if (pc_debug >= 5) + printk("0x%.2x ", pts_reply[i]); } - pr_debug("\n"); -#endif /* CM4000_DEBUG */ + printk("\n"); +#endif /* PCMCIA_DEBUG */ DEBUGP(5, dev, "Clear Tactive in Flags1\n"); xoutb(0x20, REG_FLAGS1(iobase)); @@ -647,7 +655,7 @@ static void terminate_monitor(struct cm4000_dev *dev) DEBUGP(5, dev, "Delete timer\n"); del_timer_sync(&dev->timer); -#ifdef CM4000_DEBUG +#ifdef PCMCIA_DEBUG dev->monitor_running = 0; #endif @@ -890,7 +898,7 @@ static void monitor_card(unsigned long p) DEBUGP(4, dev, "ATR checksum (0x%.2x, should " "be zero) failed\n", dev->atr_csum); } -#ifdef CM4000_DEBUG +#ifdef PCMCIA_DEBUG else if (test_bit(IS_BAD_LENGTH, &dev->flags)) { DEBUGP(4, dev, "ATR length error\n"); } else { @@ -1407,7 +1415,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int size; int rc; void __user *argp = (void __user *)arg; -#ifdef CM4000_DEBUG +#ifdef PCMCIA_DEBUG char *ioctl_names[CM_IOC_MAXNR + 1] = { [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS", [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR", @@ -1415,9 +1423,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS", [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL", }; +#endif DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode), iminor(inode), ioctl_names[_IOC_NR(cmd)]); -#endif lock_kernel(); rc = -ENODEV; @@ -1515,7 +1523,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } case CM_IOCARDOFF: -#ifdef CM4000_DEBUG +#ifdef PCMCIA_DEBUG DEBUGP(4, dev, "... in CM_IOCARDOFF\n"); if (dev->flags0 & 0x01) { DEBUGP(4, dev, " Card inserted\n"); @@ -1617,9 +1625,18 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; -#ifdef CM4000_DEBUG - case CM_IOSDBGLVL: - rc = -ENOTTY; +#ifdef PCMCIA_DEBUG + case CM_IOSDBGLVL: /* set debug log level */ + { + 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; #endif default: diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c index a6a70e476bea..4f0723b07974 100644 --- a/trunk/drivers/char/pcmcia/cm4040_cs.c +++ b/trunk/drivers/char/pcmcia/cm4040_cs.c @@ -17,6 +17,8 @@ * All rights reserved, Dual BSD/GPL Licensed. */ +/* #define PCMCIA_DEBUG 6 */ + #include #include #include @@ -39,16 +41,18 @@ #include "cm4040_cs.h" -#define reader_to_dev(x) (&x->p_dev->dev) - -/* n (debug level) is ignored */ -/* additional debug output may be enabled by re-compiling with - * CM4040_DEBUG set */ -/* #define CM4040_DEBUG */ -#define DEBUGP(n, rdr, x, args...) do { \ - dev_dbg(reader_to_dev(rdr), "%s:" x, \ - __func__ , ## args); \ +#ifdef PCMCIA_DEBUG +#define reader_to_dev(x) (&handle_to_dev(x->p_dev)) +static int pc_debug = PCMCIA_DEBUG; +module_param(pc_debug, int, 0600); +#define DEBUGP(n, rdr, x, args...) do { \ + if (pc_debug >= (n)) \ + dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ + __func__ , ##args); \ } while (0) +#else +#define DEBUGP(n, rdr, x, args...) +#endif static char *version = "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte"; @@ -86,13 +90,14 @@ struct reader_dev { static struct pcmcia_device *dev_table[CM_MAX_DEV]; -#ifndef CM4040_DEBUG +#ifndef PCMCIA_DEBUG #define xoutb outb #define xinb inb #else static inline void xoutb(unsigned char val, unsigned short port) { - pr_debug("outb(val=%.2x,port=%.4x)\n", val, port); + if (pc_debug >= 7) + printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); outb(val, port); } @@ -101,7 +106,8 @@ static inline unsigned char xinb(unsigned short port) unsigned char val; val = inb(port); - pr_debug("%.2x=inb(%.4x)\n", val, port); + if (pc_debug >= 7) + printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); return val; } #endif @@ -254,22 +260,23 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, return -EIO; } dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN); -#ifdef CM4040_DEBUG - pr_debug("%lu:%2x ", i, dev->r_buf[i]); +#ifdef PCMCIA_DEBUG + if (pc_debug >= 6) + printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); } - pr_debug("\n"); + printk("\n"); #else } #endif bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]); - DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read); + DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read); 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); - DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read); + DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read); for (i = 0; i < (min_bytes_to_read-5); i++) { rc = wait_for_bulk_in_ready(dev); @@ -281,10 +288,11 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, return -EIO; } dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN); -#ifdef CM4040_DEBUG - pr_debug("%lu:%2x ", i, dev->r_buf[i]); +#ifdef PCMCIA_DEBUG + if (pc_debug >= 6) + printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); } - pr_debug("\n"); + printk("\n"); #else } #endif @@ -539,7 +547,7 @@ static int cm4040_config_check(struct pcmcia_device *p_dev, p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; rc = pcmcia_request_io(p_dev, &p_dev->io); - dev_printk(KERN_INFO, &p_dev->dev, + dev_printk(KERN_INFO, &handle_to_dev(p_dev), "pcmcia_request_io returned 0x%x\n", rc); return rc; } @@ -561,7 +569,7 @@ static int reader_config(struct pcmcia_device *link, int devno) fail_rc = pcmcia_request_configuration(link, &link->conf); if (fail_rc != 0) { - dev_printk(KERN_INFO, &link->dev, + dev_printk(KERN_INFO, &handle_to_dev(link), "pcmcia_request_configuration failed 0x%x\n", fail_rc); goto cs_release; diff --git a/trunk/drivers/char/pcmcia/ipwireless/hardware.c b/trunk/drivers/char/pcmcia/ipwireless/hardware.c index 99cffdab1056..4c1820cad712 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/hardware.c +++ b/trunk/drivers/char/pcmcia/ipwireless/hardware.c @@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, irqreturn_t ipwireless_interrupt(int irq, void *dev_id) { - struct ipw_dev *ipw = dev_id; + struct ipw_hardware *hw = dev_id; - if (ipw->hardware->hw_version == HW_VERSION_1) - return ipwireless_handle_v1_interrupt(irq, ipw->hardware); + if (hw->hw_version == HW_VERSION_1) + return ipwireless_handle_v1_interrupt(irq, hw); else - return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware); + return ipwireless_handle_v2_v3_interrupt(irq, hw); } static void flush_packets_to_hw(struct ipw_hardware *hw) diff --git a/trunk/drivers/char/pcmcia/ipwireless/main.c b/trunk/drivers/char/pcmcia/ipwireless/main.c index dff24dae1485..5216fce0c62d 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/main.c +++ b/trunk/drivers/char/pcmcia/ipwireless/main.c @@ -65,7 +65,10 @@ static void signalled_reboot_work(struct work_struct *work_reboot) struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, work_reboot); struct pcmcia_device *link = ipw->link; - pcmcia_reset_card(link->socket); + int ret = pcmcia_reset_card(link->socket); + + if (ret != 0) + cs_error(link, ResetCard, ret); } static void signalled_reboot_callback(void *callback_data) @@ -76,127 +79,208 @@ static void signalled_reboot_callback(void *callback_data) schedule_work(&ipw->work_reboot); } -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) +static int config_ipwireless(struct ipw_dev *ipw) { - struct ipw_dev *ipw = priv_data; - struct resource *io_resource; + struct pcmcia_device *link = ipw->link; + int ret; + tuple_t tuple; + unsigned short buf[64]; + cisparse_t parse; + unsigned short cor_value; memreq_t memreq_attr_memory; memreq_t memreq_common_memory; - int ret; - 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; - p_dev->io.IOAddrLines = 16; + ipw->is_v2_card = 0; + + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *) buf; + 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. */ /* 0x04 enables IREQ pin. */ - p_dev->conf.ConfigIndex = cfg->index | 0x44; - ret = pcmcia_request_io(p_dev, &p_dev->io); - if (ret) - return ret; + cor_value = parse.cftable_entry.index | 0x44; + link->conf.ConfigIndex = cor_value; - io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1, - IPWIRELESS_PCCARD_NAME); + /* IRQ and I/O settings */ + tuple.DesiredTuple = CISTPL_CONFIG; - if (cfg->mem.nwin == 0) - return 0; + ret = pcmcia_get_first_tuple(link, &tuple); - ipw->request_common_memory.Attributes = - WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; - 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; + if (ret != 0) { + cs_error(link, GetFirstTuple, ret); + goto exit0; + } - ret = pcmcia_request_window(p_dev, &ipw->request_common_memory, - &ipw->handle_common_memory); + ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != 0) - goto exit1; + if (ret != 0) { + cs_error(link, GetTupleData, ret); + goto exit0; + } - memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr; - memreq_common_memory.Page = 0; + ret = pcmcia_parse_tuple(&tuple, &parse); - ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory, - &memreq_common_memory); + 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; - if (ret != 0) - goto exit2; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; + link->irq.Handler = ipwireless_interrupt; + link->irq.Instance = ipw->hardware; - ipw->is_v2_card = cfg->mem.win[0].len == 0x100; + ret = pcmcia_request_io(link, &link->io); - ipw->common_memory = ioremap(ipw->request_common_memory.Base, - ipw->request_common_memory.Size); - request_mem_region(ipw->request_common_memory.Base, - ipw->request_common_memory.Size, + if (ret != 0) { + cs_error(link, RequestIO, ret); + goto exit0; + } + + request_region(link->io.BasePort1, link->io.NumPorts1, IPWIRELESS_PCCARD_NAME); - ipw->request_attr_memory.Attributes = - WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; - ipw->request_attr_memory.Base = 0; - ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ - ipw->request_attr_memory.AccessSpeed = 0; + /* memory settings */ - ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory, - &ipw->handle_attr_memory); + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - if (ret != 0) - goto exit2; + ret = pcmcia_get_first_tuple(link, &tuple); - memreq_attr_memory.CardOffset = 0; - memreq_attr_memory.Page = 0; + if (ret != 0) { + cs_error(link, GetFirstTuple, ret); + goto exit1; + } - ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory, - &memreq_attr_memory); + ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != 0) - goto exit3; + if (ret != 0) { + cs_error(link, GetTupleData, ret); + goto exit1; + } - ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, - ipw->request_attr_memory.Size); - request_mem_region(ipw->request_attr_memory.Base, - ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME); + ret = pcmcia_parse_tuple(&tuple, &parse); - return 0; + if (ret != 0) { + cs_error(link, ParseTuple, ret); + goto exit1; + } -exit3: - pcmcia_release_window(p_dev, ipw->handle_attr_memory); -exit2: - if (ipw->common_memory) { - release_mem_region(ipw->request_common_memory.Base, + 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); + + if (ret != 0) { + cs_error(link, RequestWindow, ret); + goto exit1; + } + + memreq_common_memory.CardOffset = + parse.cftable_entry.mem.win[0].card_addr; + memreq_common_memory.Page = 0; + + ret = pcmcia_map_mem_page(ipw->handle_common_memory, + &memreq_common_memory); + + if (ret != 0) { + cs_error(link, MapMemPage, ret); + goto exit1; + } + + ipw->is_v2_card = + parse.cftable_entry.mem.win[0].len == 0x100; + + ipw->common_memory = ioremap(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; -} + request_mem_region(ipw->request_common_memory.Base, + ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME); -static int config_ipwireless(struct ipw_dev *ipw) -{ - struct pcmcia_device *link = ipw->link; - int ret = 0; + ipw->request_attr_memory.Attributes = + WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; + ipw->request_attr_memory.Base = 0; + ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ + ipw->request_attr_memory.AccessSpeed = 0; - ipw->is_v2_card = 0; + ret = pcmcia_request_window(&link, &ipw->request_attr_memory, + &ipw->handle_attr_memory); - ret = pcmcia_loop_config(link, ipwireless_probe, ipw); - if (ret != 0) - return ret; + if (ret != 0) { + cs_error(link, RequestWindow, ret); + goto exit2; + } - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.IntType = INT_MEMORY_AND_IO; + memreq_attr_memory.CardOffset = 0; + memreq_attr_memory.Page = 0; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = ipwireless_interrupt; + ret = pcmcia_map_mem_page(ipw->handle_attr_memory, + &memreq_attr_memory); + + if (ret != 0) { + cs_error(link, MapMemPage, ret); + goto exit2; + } + + ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, + ipw->request_attr_memory.Size); + request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size, + IPWIRELESS_PCCARD_NAME); + } INIT_WORK(&ipw->work_reboot, signalled_reboot_work); @@ -207,8 +291,10 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_irq(link, &link->irq); - if (ret != 0) - goto exit; + if (ret != 0) { + cs_error(link, RequestIRQ, ret); + goto exit3; + } printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", ipw->is_v2_card ? "V2/V3" : "V1"); @@ -230,12 +316,12 @@ static int config_ipwireless(struct ipw_dev *ipw) ipw->network = ipwireless_network_create(ipw->hardware); if (!ipw->network) - goto exit; + goto exit3; ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network, ipw->nodes); if (!ipw->tty) - goto exit; + goto exit3; ipwireless_init_hardware_v2_v3(ipw->hardware); @@ -245,27 +331,35 @@ static int config_ipwireless(struct ipw_dev *ipw) */ ret = pcmcia_request_configuration(link, &link->conf); - if (ret != 0) - goto exit; + if (ret != 0) { + cs_error(link, RequestConfiguration, ret); + goto exit4; + } link->dev_node = &ipw->nodes[0]; return 0; -exit: +exit4: + pcmcia_disable_device(link); +exit3: if (ipw->attr_memory) { release_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size); iounmap(ipw->attr_memory); - pcmcia_release_window(link, ipw->handle_attr_memory); + pcmcia_release_window(ipw->handle_attr_memory); + pcmcia_disable_device(link); } +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(link, ipw->handle_common_memory); + pcmcia_release_window(ipw->handle_common_memory); } +exit1: pcmcia_disable_device(link); +exit0: return -1; } @@ -284,9 +378,9 @@ static void release_ipwireless(struct ipw_dev *ipw) iounmap(ipw->attr_memory); } if (ipw->common_memory) - pcmcia_release_window(ipw->link, ipw->handle_common_memory); + pcmcia_release_window(ipw->handle_common_memory); if (ipw->attr_memory) - pcmcia_release_window(ipw->link, ipw->handle_attr_memory); + pcmcia_release_window(ipw->handle_attr_memory); /* Break the link with Card Services */ pcmcia_disable_device(ipw->link); @@ -312,6 +406,7 @@ static int ipwireless_attach(struct pcmcia_device *link) ipw->link = link; link->priv = ipw; + link->irq.Instance = ipw; /* Link this device into our device list. */ link->dev_node = &ipw->nodes[0]; @@ -326,6 +421,7 @@ static int ipwireless_attach(struct pcmcia_device *link) ret = config_ipwireless(ipw); if (ret != 0) { + cs_error(link, RegisterClient, ret); ipwireless_detach(link); return ret; } diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index c31a0d913d37..caf6e4d19469 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -554,6 +554,7 @@ static int mgslpc_probe(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; link->conf.Attributes = 0; @@ -571,51 +572,69 @@ static int mgslpc_probe(struct pcmcia_device *link) /* Card has been inserted. */ -static int mgslpc_ioprobe(struct pcmcia_device *p_dev, - 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; -} +#define CS_CHECK(fn, ret) \ +do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static int mgslpc_config(struct pcmcia_device *link) { MGSLPC_INFO *info = link->priv; - int ret; + tuple_t tuple; + 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) printk("mgslpc_config(0x%p)\n", link); - ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL); - if (ret != 0) - goto failed; + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + 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.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 8; link->conf.Present = PRESENT_OPTION; + link->irq.Attributes |= IRQ_HANDLE_PRESENT; link->irq.Handler = mgslpc_isr; + link->irq.Instance = info; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); info->io_base = link->io.BasePort1; info->irq_level = link->irq.AssignedIRQ; @@ -635,7 +654,8 @@ static int mgslpc_config(struct pcmcia_device *link) printk("\n"); return 0; -failed: +cs_failed: + cs_error(link, last_fn, last_ret); mgslpc_release((u_long)link); return -ENODEV; } diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index f06bb37defb1..47c2d2763456 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -31,7 +31,7 @@ enum tpm_const { TPM_MINOR = 224, /* officially assigned */ - TPM_BUFSIZE = 4096, + TPM_BUFSIZE = 2048, TPM_NUM_DEVICES = 256, }; diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index 2405f17b29dd..0b73e4ec1add 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -257,10 +257,6 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) return size; } -static int itpm; -module_param(itpm, bool, 0444); -MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)"); - /* * If interrupts are used (signaled by an irq set in the vendor structure) * tpm.c can skip polling for the data to be available as the interrupt is @@ -297,7 +293,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &chip->vendor.int_queue); status = tpm_tis_status(chip); - if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { + if ((status & TPM_STS_DATA_EXPECT) == 0) { rc = -EIO; goto out_err; } @@ -471,10 +467,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, "1.2 TPM (device-id 0x%X, rev-id %d)\n", vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); - if (itpm) - dev_info(dev, "Intel iTPM workaround enabled\n"); - - /* Figure out the capabilities */ intfcaps = ioread32(chip->vendor.iobase + @@ -637,7 +629,6 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { {"", 0}, /* User Specified */ {"", 0} /* Terminator */ }; -MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) { diff --git a/trunk/drivers/ide/ide-cs.c b/trunk/drivers/ide/ide-cs.c index dd6396384c25..063b933d864a 100644 --- a/trunk/drivers/ide/ide-cs.c +++ b/trunk/drivers/ide/ide-cs.c @@ -60,6 +60,15 @@ MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver"); 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 { @@ -89,7 +98,7 @@ static int ide_probe(struct pcmcia_device *link) { ide_info_t *info; - dev_dbg(&link->dev, "ide_attach()\n"); + DEBUG(0, "ide_attach()\n"); /* Create new ide device */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -103,6 +112,7 @@ static int ide_probe(struct pcmcia_device *link) link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = 3; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -124,7 +134,7 @@ static void ide_detach(struct pcmcia_device *link) ide_hwif_t *hwif = info->host->ports[0]; unsigned long data_addr, ctl_addr; - dev_dbg(&link->dev, "ide_detach(0x%p)\n", link); + DEBUG(0, "ide_detach(0x%p)\n", link); data_addr = hwif->io_ports.data_addr; ctl_addr = hwif->io_ports.ctl_addr; @@ -207,6 +217,9 @@ 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 { unsigned long ctl_base; int skip_vcc; @@ -269,11 +282,11 @@ static int ide_config(struct pcmcia_device *link) { ide_info_t *info = link->priv; struct pcmcia_config_check *stk = NULL; - int ret = 0, is_kme = 0; + int last_ret = 0, last_fn = 0, is_kme = 0; unsigned long io_base, ctl_base; struct ide_host *host; - dev_dbg(&link->dev, "ide_config(0x%p)\n", link); + DEBUG(0, "ide_config(0x%p)\n", link); is_kme = ((link->manf_id == MANFID_KME) && ((link->card_id == PRODID_KME_KXLC005_A) || @@ -293,12 +306,8 @@ static int ide_config(struct pcmcia_device *link) io_base = link->io.BasePort1; ctl_base = stk->ctl_base; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* disable drive interrupts during IDE probe */ outb(0x02, ctl_base); @@ -333,6 +342,8 @@ static int ide_config(struct pcmcia_device *link) printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n"); goto failed; +cs_failed: + cs_error(link, last_fn, last_ret); failed: kfree(stk); ide_release(link); @@ -352,7 +363,7 @@ static void ide_release(struct pcmcia_device *link) ide_info_t *info = link->priv; struct ide_host *host = info->host; - dev_dbg(&link->dev, "ide_release(0x%p)\n", link); + DEBUG(0, "ide_release(0x%p)\n", link); if (info->ndev) /* FIXME: if this fails we need to queue the cleanup somehow diff --git a/trunk/drivers/isdn/hardware/avm/avm_cs.c b/trunk/drivers/isdn/hardware/avm/avm_cs.c index 5a6ae646a636..c72565520e41 100644 --- a/trunk/drivers/isdn/hardware/avm/avm_cs.c +++ b/trunk/drivers/isdn/hardware/avm/avm_cs.c @@ -111,6 +111,8 @@ static int avmcs_probe(struct pcmcia_device *p_dev) p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -196,6 +198,7 @@ static int avmcs_config(struct pcmcia_device *link) */ i = pcmcia_request_irq(link, &link->irq); if (i != 0) { + cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); break; @@ -206,6 +209,7 @@ static int avmcs_config(struct pcmcia_device *link) */ i = pcmcia_request_configuration(link, &link->conf); if (i != 0) { + cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; } diff --git a/trunk/drivers/isdn/hisax/avma1_cs.c b/trunk/drivers/isdn/hisax/avma1_cs.c index f9bdff39cf4a..23560c897ec3 100644 --- a/trunk/drivers/isdn/hisax/avma1_cs.c +++ b/trunk/drivers/isdn/hisax/avma1_cs.c @@ -30,6 +30,22 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA car MODULE_AUTHOR("Carsten Paeth"); 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 /*====================================================================*/ @@ -103,7 +119,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev) { local_info_t *local; - dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); + DEBUG(0, "avma1cs_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); @@ -123,6 +139,8 @@ static int avma1cs_probe(struct pcmcia_device *p_dev) p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + /* General socket configuration */ p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; @@ -143,7 +161,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev) static void avma1cs_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); + DEBUG(0, "avma1cs_detach(0x%p)\n", link); avma1cs_release(link); kfree(link->priv); } /* avma1cs_detach */ @@ -185,7 +203,7 @@ static int avma1cs_config(struct pcmcia_device *link) dev = link->priv; - dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link); + DEBUG(0, "avma1cs_config(0x%p)\n", link); devname[0] = 0; if (link->prod_id[1]) @@ -200,6 +218,7 @@ static int avma1cs_config(struct pcmcia_device *link) */ i = pcmcia_request_irq(link, &link->irq); if (i != 0) { + cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); break; @@ -210,6 +229,7 @@ static int avma1cs_config(struct pcmcia_device *link) */ i = pcmcia_request_configuration(link, &link->conf); if (i != 0) { + cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; } @@ -261,7 +281,7 @@ static void avma1cs_release(struct pcmcia_device *link) { local_info_t *local = link->priv; - dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link); + DEBUG(0, "avma1cs_release(0x%p)\n", link); /* now unregister function with hisax */ HiSax_closecard(local->node.minor); diff --git a/trunk/drivers/isdn/hisax/elsa_cs.c b/trunk/drivers/isdn/hisax/elsa_cs.c index a2f709f53974..f4d0fe29bcf8 100644 --- a/trunk/drivers/isdn/hisax/elsa_cs.c +++ b/trunk/drivers/isdn/hisax/elsa_cs.c @@ -57,6 +57,23 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards"); MODULE_AUTHOR("Klaus Lichtenwalder"); 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 /*====================================================================*/ @@ -125,7 +142,7 @@ static int elsa_cs_probe(struct pcmcia_device *link) { local_info_t *local; - dev_dbg(&link->dev, "elsa_cs_attach()\n"); + DEBUG(0, "elsa_cs_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); @@ -138,6 +155,7 @@ static int elsa_cs_probe(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID; link->irq.Handler = NULL; /* @@ -170,7 +188,7 @@ static void elsa_cs_detach(struct pcmcia_device *link) { local_info_t *info = link->priv; - dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link); + DEBUG(0, "elsa_cs_detach(0x%p)\n", link); info->busy = 1; elsa_cs_release(link); @@ -213,25 +231,30 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, static int elsa_cs_config(struct pcmcia_device *link) { local_info_t *dev; - int i; + int i, last_fn; IsdnCard_t icard; - dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); + DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); - if (i != 0) - goto failed; + if (i != 0) { + last_fn = RequestIO; + goto cs_failed; + } i = pcmcia_request_irq(link, &link->irq); if (i != 0) { link->irq.AssignedIRQ = 0; - goto failed; + last_fn = RequestIRQ; + goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) - goto failed; + if (i != 0) { + last_fn = RequestConfiguration; + goto cs_failed; + } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ @@ -267,7 +290,8 @@ static int elsa_cs_config(struct pcmcia_device *link) ((local_info_t*)link->priv)->cardnr = i; return 0; -failed: +cs_failed: + cs_error(link, last_fn, i); elsa_cs_release(link); return -ENODEV; } /* elsa_cs_config */ @@ -284,7 +308,7 @@ static void elsa_cs_release(struct pcmcia_device *link) { local_info_t *local = link->priv; - dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link); + DEBUG(0, "elsa_cs_release(0x%p)\n", link); if (local) { if (local->cardnr >= 0) { diff --git a/trunk/drivers/isdn/hisax/sedlbauer_cs.c b/trunk/drivers/isdn/hisax/sedlbauer_cs.c index af5d393cc2d0..9a3c9f5e4fe8 100644 --- a/trunk/drivers/isdn/hisax/sedlbauer_cs.c +++ b/trunk/drivers/isdn/hisax/sedlbauer_cs.c @@ -57,6 +57,24 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards"); MODULE_AUTHOR("Marcus Niemann"); 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 + /*====================================================================*/ @@ -133,7 +151,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) { local_info_t *local; - dev_dbg(&link->dev, "sedlbauer_attach()\n"); + DEBUG(0, "sedlbauer_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); @@ -145,6 +163,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; /* @@ -179,7 +198,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) static void sedlbauer_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); + DEBUG(0, "sedlbauer_detach(0x%p)\n", link); ((local_info_t *)link->priv)->stop = 1; sedlbauer_release(link); @@ -195,6 +214,9 @@ static void sedlbauer_detach(struct pcmcia_device *link) 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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -271,11 +293,11 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, req->Base = mem->win[0].host_addr; req->Size = mem->win[0].len; 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; map.Page = 0; map.CardOffset = mem->win[0].card_addr; - if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0) + if (pcmcia_map_mem_page(p_dev->win, &map) != 0) return -ENODEV; } return 0; @@ -287,10 +309,10 @@ static int sedlbauer_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; win_req_t *req; - int ret; + int last_fn, last_ret; IsdnCard_t icard; - dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link); + DEBUG(0, "sedlbauer_config(0x%p)\n", link); req = kzalloc(sizeof(win_req_t), GFP_KERNEL); if (!req) @@ -308,8 +330,8 @@ static int sedlbauer_config(struct pcmcia_device *link) these things without consulting the CIS, and most client drivers will only use the CIS to fill in implementation-defined details. */ - ret = pcmcia_loop_config(link, sedlbauer_config_check, req); - if (ret) + last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req); + if (last_ret) goto failed; /* @@ -317,20 +339,15 @@ static int sedlbauer_config(struct pcmcia_device *link) handler to the interrupt, unless the 'Handler' member of the irq structure is initialized. */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (link->conf.Attributes & CONF_ENABLE_IRQ) + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* At this point, the dev_node_t structure(s) need to be @@ -363,18 +380,19 @@ static int sedlbauer_config(struct pcmcia_device *link) icard.protocol = protocol; icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; - ret = hisax_init_pcmcia(link, - &(((local_info_t *)link->priv)->stop), &icard); - if (ret < 0) { - printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n", - ret, link->io.BasePort1); + last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard); + if (last_ret < 0) { + printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n", + last_ret, link->io.BasePort1); sedlbauer_release(link); return -ENODEV; } else - ((local_info_t *)link->priv)->cardnr = ret; + ((local_info_t*)link->priv)->cardnr = last_ret; return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: sedlbauer_release(link); return -ENODEV; @@ -392,7 +410,7 @@ static int sedlbauer_config(struct pcmcia_device *link) static void sedlbauer_release(struct pcmcia_device *link) { local_info_t *local = link->priv; - dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link); + DEBUG(0, "sedlbauer_release(0x%p)\n", link); if (local) { if (local->cardnr >= 0) { diff --git a/trunk/drivers/isdn/hisax/teles_cs.c b/trunk/drivers/isdn/hisax/teles_cs.c index ea705394ce2b..623d111544d4 100644 --- a/trunk/drivers/isdn/hisax/teles_cs.c +++ b/trunk/drivers/isdn/hisax/teles_cs.c @@ -38,6 +38,23 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards"); MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de"); 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 /*====================================================================*/ @@ -116,7 +133,7 @@ static int teles_probe(struct pcmcia_device *link) { local_info_t *local; - dev_dbg(&link->dev, "teles_attach()\n"); + DEBUG(0, "teles_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(local_info_t), GFP_KERNEL); @@ -128,6 +145,7 @@ static int teles_probe(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID; link->irq.Handler = NULL; /* @@ -160,7 +178,7 @@ static void teles_detach(struct pcmcia_device *link) { local_info_t *info = link->priv; - dev_dbg(&link->dev, "teles_detach(0x%p)\n", link); + DEBUG(0, "teles_detach(0x%p)\n", link); info->busy = 1; teles_cs_release(link); @@ -203,25 +221,30 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, static int teles_cs_config(struct pcmcia_device *link) { local_info_t *dev; - int i; + int i, last_fn; IsdnCard_t icard; - dev_dbg(&link->dev, "teles_config(0x%p)\n", link); + DEBUG(0, "teles_config(0x%p)\n", link); dev = link->priv; i = pcmcia_loop_config(link, teles_cs_configcheck, NULL); - if (i != 0) + if (i != 0) { + last_fn = RequestIO; goto cs_failed; + } i = pcmcia_request_irq(link, &link->irq); if (i != 0) { link->irq.AssignedIRQ = 0; + last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if (i != 0) { + last_fn = RequestConfiguration; goto cs_failed; + } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ @@ -260,6 +283,7 @@ static int teles_cs_config(struct pcmcia_device *link) return 0; cs_failed: + cs_error(link, last_fn, i); teles_cs_release(link); return -ENODEV; } /* teles_cs_config */ @@ -276,7 +300,7 @@ static void teles_cs_release(struct pcmcia_device *link) { local_info_t *local = link->priv; - dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link); + DEBUG(0, "teles_cs_release(0x%p)\n", link); if (local) { if (local->cardnr >= 0) { diff --git a/trunk/drivers/mtd/maps/pcmciamtd.c b/trunk/drivers/mtd/maps/pcmciamtd.c index 689d6a79ffc0..d600c2deff73 100644 --- a/trunk/drivers/mtd/maps/pcmciamtd.c +++ b/trunk/drivers/mtd/maps/pcmciamtd.c @@ -118,9 +118,11 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x", dev->offset, mrq.CardOffset); mrq.Page = 0; - ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq); - if (ret != 0) + ret = pcmcia_map_mem_page(win, &mrq); + if (ret != 0) { + cs_error(dev->p_dev, MapMemPage, ret); return NULL; + } dev->offset = mrq.CardOffset; } return dev->win_base + (to & (dev->win_size-1)); @@ -325,6 +327,8 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); ret = pcmcia_modify_configuration(link, &mod); + if (ret != 0) + cs_error(link, ModifyConfiguration, ret); } @@ -344,116 +348,107 @@ static void pcmciamtd_release(struct pcmcia_device *link) iounmap(dev->win_base); dev->win_base = NULL; } - pcmcia_release_window(link, link->win); + pcmcia_release_window(link->win); } 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) +static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) { - struct pcmciamtd_dev *dev = priv_data; + int rc; + tuple_t tuple; cisparse_t parse; - cistpl_device_t *t = &parse.device; - int i; + u_char buf[64]; + + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = RETURN_FIRST_TUPLE; + + rc = pcmcia_get_first_tuple(link, &tuple); + 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); + if (rc != 0) { + cs_error(link, ParseTuple, rc); + break; + } - 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; -} + 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; -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; -} + 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; + } -static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) -{ - int i; + 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; + } - if (p_dev->prod_id[0]) { - dev->mtd_name[0] = '\0'; - for (i = 0; i < 4; i++) { - if (i) - strcat(dev->mtd_name, " "); - if (p_dev->prod_id[i]) - strcat(dev->mtd_name, p_dev->prod_id[i]); + 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; } - DEBUG(2, "Found name: %s", dev->mtd_name); - } -#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); + default: + DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); + } + rc = pcmcia_get_next_tuple(link, &tuple); + } if(!dev->pcmcia_map.size) dev->pcmcia_map.size = MAX_PCMCIA_ADDR; @@ -486,12 +481,16 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, * 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) { struct pcmciamtd_dev *dev = link->priv; struct mtd_info *mtd = NULL; cs_status_t status; win_req_t req; + int last_ret = 0, last_fn = 0; int ret; int i; static char *probes[] = { "jedec_probe", "cfi_probe" }; @@ -530,7 +529,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) int ret; DEBUG(2, "requesting window with size = %dKiB memspeed = %d", 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); if(ret) { req.Size >>= 1; @@ -578,6 +577,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) DEBUG(2, "Setting Configuration"); ret = pcmcia_request_configuration(link, &link->conf); if (ret != 0) { + cs_error(link, RequestConfiguration, ret); if (dev->win_base) { iounmap(dev->win_base); dev->win_base = NULL; @@ -652,7 +652,8 @@ static int pcmciamtd_config(struct pcmcia_device *link) link->dev_node = &dev->node; return 0; - failed: + cs_failed: + cs_error(link, last_fn, last_ret); err("CS Error, exiting"); pcmciamtd_release(link); return -ENODEV; diff --git a/trunk/drivers/net/pcmcia/3c574_cs.c b/trunk/drivers/net/pcmcia/3c574_cs.c index 17a27225cc98..b58965a2b3ae 100644 --- a/trunk/drivers/net/pcmcia/3c574_cs.c +++ b/trunk/drivers/net/pcmcia/3c574_cs.c @@ -118,6 +118,14 @@ INT_MODULE_PARM(full_duplex, 0); /* Autodetect link polarity reversal? */ 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 /*====================================================================*/ @@ -270,7 +278,7 @@ static int tc574_probe(struct pcmcia_device *link) struct el3_private *lp; struct net_device *dev; - dev_dbg(&link->dev, "3c574_attach()\n"); + DEBUG(0, "3c574_attach()\n"); /* Create the PC card device object. */ dev = alloc_etherdev(sizeof(struct el3_private)); @@ -283,8 +291,10 @@ static int tc574_probe(struct pcmcia_device *link) spin_lock_init(&lp->window_lock); link->io.NumPorts1 = 32; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - 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 = &el3_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -309,7 +319,7 @@ static void tc574_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "3c574_detach()\n"); + DEBUG(0, "3c574_detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -325,23 +335,26 @@ static void tc574_detach(struct pcmcia_device *link) 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 int tc574_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); - int ret, i, j; + tuple_t tuple; + __le16 buf[32]; + int last_fn, last_ret, i, j; unsigned int ioaddr; __be16 *phys_addr; char *cardname; __u32 config; - u8 *buf; - size_t len; phys_addr = (__be16 *)dev->dev_addr; - dev_dbg(&link->dev, "3c574_config()\n"); + DEBUG(0, "3c574_config(0x%p)\n", link); link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x20) { @@ -350,16 +363,12 @@ static int tc574_config(struct pcmcia_device *link) if (i == 0) break; } - if (i != 0) - goto failed; - - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) + if (i != 0) { + cs_error(link, RequestIO, i); 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->base_addr = link->io.BasePort1; @@ -369,14 +378,16 @@ static int tc574_config(struct pcmcia_device *link) /* The 3c574 normally uses an EEPROM for configuration info, including the hardware address. The future products may include a modem chip and put the address in the CIS. */ - - len = pcmcia_get_tuple(link, 0x88, &buf); - if (buf && len >= 6) { + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = 64; + 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++) - phys_addr[i] = htons(le16_to_cpu(buf[i * 2])); - kfree(buf); + phys_addr[i] = htons(le16_to_cpu(buf[i])); } else { - kfree(buf); /* 0 < len < 6 */ EL3WINDOW(0); for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i + 10)); @@ -424,8 +435,7 @@ static int tc574_config(struct pcmcia_device *link) mii_status = mdio_read(ioaddr, phy & 0x1f, 1); if (mii_status != 0xffff) { lp->phys = phy & 0x1f; - dev_dbg(&link->dev, " MII transceiver at " - "index %d, status %x.\n", + DEBUG(0, " MII transceiver at index %d, status %x.\n", phy, mii_status); if ((mii_status & 0x0040) == 0) mii_preamble_required = 1; @@ -447,7 +457,7 @@ static int tc574_config(struct pcmcia_device *link) } link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); @@ -468,6 +478,8 @@ static int tc574_config(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: tc574_release(link); return -ENODEV; @@ -726,7 +738,7 @@ static int el3_open(struct net_device *dev) lp->media.expires = jiffies + HZ; add_timer(&lp->media); - dev_dbg(&link->dev, "%s: opened, status %4.4x.\n", + DEBUG(2, "%s: opened, status %4.4x.\n", dev->name, inw(dev->base_addr + EL3_STATUS)); return 0; @@ -760,7 +772,7 @@ static void pop_tx_status(struct net_device *dev) if (tx_status & 0x30) tc574_wait_for_completion(dev, TxReset); if (tx_status & 0x38) { - pr_debug("%s: transmit error: status 0x%02x\n", + DEBUG(1, "%s: transmit error: status 0x%02x\n", dev->name, tx_status); outw(TxEnable, ioaddr + EL3_CMD); dev->stats.tx_aborted_errors++; @@ -776,7 +788,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb, struct el3_private *lp = netdev_priv(dev); unsigned long flags; - pr_debug("%s: el3_start_xmit(length = %ld) called, " + DEBUG(3, "%s: el3_start_xmit(length = %ld) called, " "status %4.4x.\n", dev->name, (long)skb->len, inw(ioaddr + EL3_STATUS)); @@ -815,7 +827,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) return IRQ_NONE; ioaddr = dev->base_addr; - pr_debug("%s: interrupt, status %4.4x.\n", + DEBUG(3, "%s: interrupt, status %4.4x.\n", dev->name, inw(ioaddr + EL3_STATUS)); spin_lock(&lp->window_lock); @@ -824,7 +836,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) (IntLatch | RxComplete | RxEarly | StatsFull)) { if (!netif_device_present(dev) || ((status & 0xe000) != 0x2000)) { - pr_debug("%s: Interrupt from dead card\n", dev->name); + DEBUG(1, "%s: Interrupt from dead card\n", dev->name); break; } @@ -834,7 +846,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) work_budget = el3_rx(dev, work_budget); if (status & TxAvailable) { - pr_debug(" TX room bit was handled.\n"); + DEBUG(3, " TX room bit was handled.\n"); /* There's room in the FIFO for a full-sized packet. */ outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); netif_wake_queue(dev); @@ -874,7 +886,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) } if (--work_budget < 0) { - pr_debug("%s: Too much work in interrupt, " + DEBUG(0, "%s: Too much work in interrupt, " "status %4.4x.\n", dev->name, status); /* Clear all interrupts */ outw(AckIntr | 0xFF, ioaddr + EL3_CMD); @@ -884,7 +896,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); } - pr_debug("%s: exiting interrupt, status %4.4x.\n", + DEBUG(3, "%s: exiting interrupt, status %4.4x.\n", dev->name, inw(ioaddr + EL3_STATUS)); spin_unlock(&lp->window_lock); @@ -991,7 +1003,7 @@ static void update_stats(struct net_device *dev) unsigned int ioaddr = dev->base_addr; u8 rx, tx, up; - pr_debug("%s: updating the statistics.\n", dev->name); + DEBUG(2, "%s: updating the statistics.\n", dev->name); if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */ return; @@ -1027,7 +1039,7 @@ static int el3_rx(struct net_device *dev, int worklimit) unsigned int ioaddr = dev->base_addr; short rx_status; - pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", + DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus)); while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) && worklimit > 0) { @@ -1049,7 +1061,7 @@ static int el3_rx(struct net_device *dev, int worklimit) skb = dev_alloc_skb(pkt_len+5); - pr_debug(" Receiving packet size %d status %4.4x.\n", + DEBUG(3, " Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); if (skb != NULL) { skb_reserve(skb, 2); @@ -1060,7 +1072,7 @@ static int el3_rx(struct net_device *dev, int worklimit) dev->stats.rx_packets++; dev->stats.rx_bytes += pkt_len; } else { - pr_debug("%s: couldn't allocate a sk_buff of" + DEBUG(1, "%s: couldn't allocate a sk_buff of" " size %d.\n", dev->name, pkt_len); dev->stats.rx_dropped++; } @@ -1089,7 +1101,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) struct mii_ioctl_data *data = if_mii(rq); int phy = lp->phys & 0x1f; - pr_debug("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n", + DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n", dev->name, rq->ifr_ifrn.ifrn_name, cmd, data->phy_id, data->reg_num, data->val_in, data->val_out); @@ -1166,7 +1178,7 @@ static int el3_close(struct net_device *dev) struct el3_private *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; - dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name); + DEBUG(2, "%s: shutting down ethercard.\n", dev->name); if (pcmcia_dev_present(link)) { unsigned long flags; diff --git a/trunk/drivers/net/pcmcia/3c589_cs.c b/trunk/drivers/net/pcmcia/3c589_cs.c index 6f8d7e2e5922..569fb06793cf 100644 --- a/trunk/drivers/net/pcmcia/3c589_cs.c +++ b/trunk/drivers/net/pcmcia/3c589_cs.c @@ -130,6 +130,14 @@ MODULE_LICENSE("GPL"); /* Special hook for setting if_port when module is loaded */ 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 /*====================================================================*/ @@ -181,7 +189,7 @@ static int tc589_probe(struct pcmcia_device *link) struct el3_private *lp; struct net_device *dev; - dev_dbg(&link->dev, "3c589_attach()\n"); + DEBUG(0, "3c589_attach()\n"); /* Create new ethernet device */ dev = alloc_etherdev(sizeof(struct el3_private)); @@ -194,8 +202,10 @@ static int tc589_probe(struct pcmcia_device *link) spin_lock_init(&lp->lock); link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - 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 = &el3_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -221,7 +231,7 @@ static void tc589_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "3c589_detach\n"); + DEBUG(0, "3c589_detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -239,20 +249,29 @@ 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) { struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); + tuple_t tuple; + __le16 buf[32]; __be16 *phys_addr; - int ret, i, j, multi = 0, fifo; + int last_fn, last_ret, i, j, multi = 0, fifo; unsigned int ioaddr; char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; - u8 *buf; - size_t len; - dev_dbg(&link->dev, "3c589_config\n"); + DEBUG(0, "3c589_config(0x%p)\n", link); 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? */ if (link->manf_id != MANFID_3COM) printk(KERN_INFO "3c589_cs: hmmm, is this really a " @@ -268,16 +287,12 @@ static int tc589_config(struct pcmcia_device *link) if (i == 0) 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; + } + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -286,13 +301,12 @@ static int tc589_config(struct pcmcia_device *link) /* The 3c589 has an extra EEPROM for configuration info, including the hardware address. The 3c562 puts the address in the CIS. */ - len = pcmcia_get_tuple(link, 0x88, &buf); - if (buf && len >= 6) { - for (i = 0; i < 3; i++) - phys_addr[i] = htons(le16_to_cpu(buf[i*2])); - kfree(buf); + tuple.DesiredTuple = 0x88; + if (pcmcia_get_first_tuple(link, &tuple) == 0) { + pcmcia_get_tuple_data(link, &tuple); + for (i = 0; i < 3; i++) + phys_addr[i] = htons(le16_to_cpu(buf[i])); } else { - kfree(buf); /* 0 < len < 6 */ for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i)); if (phys_addr[0] == htons(0x6060)) { @@ -314,7 +328,7 @@ static int tc589_config(struct pcmcia_device *link) printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); @@ -333,6 +347,8 @@ static int tc589_config(struct pcmcia_device *link) if_names[dev->if_port]); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: tc589_release(link); return -ENODEV; @@ -495,8 +511,24 @@ static void netdev_get_drvinfo(struct net_device *dev, 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 = { .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) @@ -531,7 +563,7 @@ static int el3_open(struct net_device *dev) lp->media.expires = jiffies + HZ; add_timer(&lp->media); - dev_dbg(&link->dev, "%s: opened, status %4.4x.\n", + DEBUG(1, "%s: opened, status %4.4x.\n", dev->name, inw(dev->base_addr + EL3_STATUS)); return 0; @@ -564,7 +596,7 @@ static void pop_tx_status(struct net_device *dev) if (tx_status & 0x30) tc589_wait_for_completion(dev, TxReset); if (tx_status & 0x38) { - pr_debug("%s: transmit error: status 0x%02x\n", + DEBUG(1, "%s: transmit error: status 0x%02x\n", dev->name, tx_status); outw(TxEnable, ioaddr + EL3_CMD); dev->stats.tx_aborted_errors++; @@ -580,7 +612,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb, struct el3_private *priv = netdev_priv(dev); unsigned long flags; - pr_debug("%s: el3_start_xmit(length = %ld) called, " + DEBUG(3, "%s: el3_start_xmit(length = %ld) called, " "status %4.4x.\n", dev->name, (long)skb->len, inw(ioaddr + EL3_STATUS)); @@ -622,14 +654,14 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) ioaddr = dev->base_addr; - pr_debug("%s: interrupt, status %4.4x.\n", + DEBUG(3, "%s: interrupt, status %4.4x.\n", dev->name, inw(ioaddr + EL3_STATUS)); spin_lock(&lp->lock); while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete | StatsFull)) { if ((status & 0xe000) != 0x2000) { - pr_debug("%s: interrupt from dead card\n", dev->name); + DEBUG(1, "%s: interrupt from dead card\n", dev->name); handled = 0; break; } @@ -638,7 +670,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) el3_rx(dev); if (status & TxAvailable) { - pr_debug(" TX room bit was handled.\n"); + DEBUG(3, " TX room bit was handled.\n"); /* There's room in the FIFO for a full-sized packet. */ outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); netif_wake_queue(dev); @@ -690,7 +722,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) lp->last_irq = jiffies; spin_unlock(&lp->lock); - pr_debug("%s: exiting interrupt, status %4.4x.\n", + DEBUG(3, "%s: exiting interrupt, status %4.4x.\n", dev->name, inw(ioaddr + EL3_STATUS)); return IRQ_RETVAL(handled); } @@ -801,7 +833,7 @@ static void update_stats(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; - pr_debug("%s: updating the statistics.\n", dev->name); + DEBUG(2, "%s: updating the statistics.\n", dev->name); /* Turn off statistics updates while reading. */ outw(StatsDisable, ioaddr + EL3_CMD); /* Switch to the stats window, and read everything. */ @@ -829,7 +861,7 @@ static int el3_rx(struct net_device *dev) int worklimit = 32; short rx_status; - pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", + DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) && worklimit > 0) { @@ -851,7 +883,7 @@ static int el3_rx(struct net_device *dev) skb = dev_alloc_skb(pkt_len+5); - pr_debug(" Receiving packet size %d status %4.4x.\n", + DEBUG(3, " Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); if (skb != NULL) { skb_reserve(skb, 2); @@ -862,7 +894,7 @@ static int el3_rx(struct net_device *dev) dev->stats.rx_packets++; dev->stats.rx_bytes += pkt_len; } else { - pr_debug("%s: couldn't allocate a sk_buff of" + DEBUG(1, "%s: couldn't allocate a sk_buff of" " size %d.\n", dev->name, pkt_len); dev->stats.rx_dropped++; } @@ -903,7 +935,7 @@ static int el3_close(struct net_device *dev) struct pcmcia_device *link = lp->p_dev; unsigned int ioaddr = dev->base_addr; - dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name); + DEBUG(1, "%s: shutting down ethercard.\n", dev->name); if (pcmcia_dev_present(link)) { /* Turn off statistics ASAP. We update dev->stats below. */ diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index 800597b82d18..3131a59a8d32 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -75,6 +75,16 @@ MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver"); 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 /*====================================================================*/ @@ -157,7 +167,7 @@ static int axnet_probe(struct pcmcia_device *link) struct net_device *dev; struct ei_device *ei_local; - dev_dbg(&link->dev, "axnet_attach()\n"); + DEBUG(0, "axnet_attach()\n"); dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t)); if (!dev) @@ -170,6 +180,7 @@ static int axnet_probe(struct pcmcia_device *link) info->p_dev = link; link->priv = dev; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -194,7 +205,7 @@ static void axnet_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link); + DEBUG(0, "axnet_detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -261,6 +272,9 @@ 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) { int j, ret; @@ -327,29 +341,26 @@ static int axnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); - int i, j, j2, ret; + int i, j, j2, last_ret, last_fn; - dev_dbg(&link->dev, "axnet_config(0x%p)\n", link); + DEBUG(0, "axnet_config(0x%p)\n", link); /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; - ret = pcmcia_loop_config(link, axnet_configcheck, NULL); - if (ret != 0) + last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL); + if (last_ret != 0) { + cs_error(link, RequestIO, last_ret); goto failed; + } - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); if (link->io.NumPorts2 == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; } - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; - + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -399,7 +410,7 @@ static int axnet_config(struct pcmcia_device *link) info->phy_id = (i < 32) ? i : -1; link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); @@ -415,12 +426,14 @@ static int axnet_config(struct pcmcia_device *link) dev->base_addr, dev->irq, dev->dev_addr); if (info->phy_id != -1) { - dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j); + DEBUG(0, " MII transceiver at index %d, status %x.\n", info->phy_id, j); } else { printk(KERN_NOTICE " No MII transceivers found!\n"); } return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: axnet_release(link); return -ENODEV; @@ -530,7 +543,7 @@ static int axnet_open(struct net_device *dev) struct pcmcia_device *link = info->p_dev; unsigned int nic_base = dev->base_addr; - dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name); + DEBUG(2, "axnet_open('%s')\n", dev->name); if (!pcmcia_dev_present(link)) return -ENODEV; @@ -559,7 +572,7 @@ static int axnet_close(struct net_device *dev) axnet_dev_t *info = PRIV(dev); struct pcmcia_device *link = info->p_dev; - dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name); + DEBUG(2, "axnet_close('%s')\n", dev->name); ax_close(dev); free_irq(dev->irq, dev); @@ -728,8 +741,10 @@ static void block_input(struct net_device *dev, int count, int xfer_count = count; char *buf = skb->data; +#ifdef PCMCIA_DEBUG if ((ei_debug > 4) && (count != 4)) - pr_debug("%s: [bi=%d]\n", dev->name, count+4); + printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4); +#endif outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD); @@ -747,7 +762,10 @@ static void block_output(struct net_device *dev, int count, { unsigned int nic_base = dev->base_addr; - pr_debug("%s: [bo=%d]\n", dev->name, count); +#ifdef PCMCIA_DEBUG + 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? What effect will an odd byte count have on the 8390? diff --git a/trunk/drivers/net/pcmcia/com20020_cs.c b/trunk/drivers/net/pcmcia/com20020_cs.c index 21d9c9d815d1..7b5c77b7bd27 100644 --- a/trunk/drivers/net/pcmcia/com20020_cs.c +++ b/trunk/drivers/net/pcmcia/com20020_cs.c @@ -53,7 +53,11 @@ #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n" -#ifdef DEBUG +#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 void regdump(struct net_device *dev) { @@ -88,6 +92,7 @@ static void regdump(struct net_device *dev) #else +#define DEBUG(n, args...) do { } while (0) static inline void regdump(struct net_device *dev) { } #endif @@ -139,7 +144,7 @@ static int com20020_probe(struct pcmcia_device *p_dev) struct net_device *dev; struct arcnet_local *lp; - dev_dbg(&p_dev->dev, "com20020_attach()\n"); + DEBUG(0, "com20020_attach()\n"); /* Create new network device */ info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL); @@ -164,10 +169,11 @@ static int com20020_probe(struct pcmcia_device *p_dev) p_dev->io.NumPorts1 = 16; p_dev->io.IOAddrLines = 16; p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->conf.IntType = INT_MEMORY_AND_IO; - info->dev = dev; + p_dev->irq.Instance = info->dev = dev; p_dev->priv = info; return com20020_config(p_dev); @@ -192,12 +198,12 @@ static void com20020_detach(struct pcmcia_device *link) struct com20020_dev_t *info = link->priv; struct net_device *dev = info->dev; - dev_dbg(&link->dev, "detach...\n"); + DEBUG(1,"detach...\n"); - dev_dbg(&link->dev, "com20020_detach\n"); + DEBUG(0, "com20020_detach(0x%p)\n", link); if (link->dev_node) { - dev_dbg(&link->dev, "unregister...\n"); + DEBUG(1,"unregister...\n"); unregister_netdev(dev); @@ -212,16 +218,16 @@ static void com20020_detach(struct pcmcia_device *link) com20020_release(link); /* Unlink device structure, free bits */ - dev_dbg(&link->dev, "unlinking...\n"); + DEBUG(1,"unlinking...\n"); if (link->priv) { dev = info->dev; if (dev) { - dev_dbg(&link->dev, "kfree...\n"); + DEBUG(1,"kfree...\n"); free_netdev(dev); } - dev_dbg(&link->dev, "kfree2...\n"); + DEBUG(1,"kfree2...\n"); kfree(info); } @@ -235,22 +241,25 @@ 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) { struct arcnet_local *lp; com20020_dev_t *info; struct net_device *dev; - int i, ret; + int i, last_ret, last_fn; int ioaddr; info = link->priv; dev = info->dev; - dev_dbg(&link->dev, "config...\n"); + DEBUG(1,"config...\n"); - dev_dbg(&link->dev, "com20020_config\n"); + DEBUG(0, "com20020_config(0x%p)\n", link); - dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1); + DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); i = -ENODEV; if (!link->io.BasePort1) { @@ -267,27 +276,26 @@ static int com20020_config(struct pcmcia_device *link) if (i != 0) { - dev_dbg(&link->dev, "requestIO failed totally!\n"); + DEBUG(1,"arcnet: requestIO failed totally!\n"); goto failed; } ioaddr = dev->base_addr = link->io.BasePort1; - dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr); + DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr); - dev_dbg(&link->dev, "request IRQ %d\n", - link->irq.AssignedIRQ); + DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n", + link->irq.AssignedIRQ, + link->irq.IRQInfo1, link->irq.IRQInfo2); i = pcmcia_request_irq(link, &link->irq); if (i != 0) { - dev_dbg(&link->dev, "requestIRQ failed totally!\n"); + DEBUG(1,"arcnet: requestIRQ failed totally!\n"); goto failed; } dev->irq = link->irq.AssignedIRQ; - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if (com20020_check(dev)) { @@ -300,25 +308,26 @@ static int com20020_config(struct pcmcia_device *link) lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = com20020_found(dev, 0); /* calls register_netdev */ if (i != 0) { - dev_printk(KERN_NOTICE, &link->dev, - "com20020_cs: com20020_found() failed\n"); + DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n"); link->dev_node = NULL; goto failed; } strcpy(info->node.dev_name, dev->name); - dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n", + DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n", dev->name, dev->base_addr, dev->irq); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: - dev_dbg(&link->dev, "com20020_config failed...\n"); + DEBUG(1,"com20020_config failed...\n"); com20020_release(link); return -ENODEV; } /* com20020_config */ @@ -333,7 +342,7 @@ static int com20020_config(struct pcmcia_device *link) static void com20020_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "com20020_release\n"); + DEBUG(0, "com20020_release(0x%p)\n", link); pcmcia_disable_device(link); } diff --git a/trunk/drivers/net/pcmcia/fmvj18x_cs.c b/trunk/drivers/net/pcmcia/fmvj18x_cs.c index 6e3e1ced6db4..7e01fbdb87e0 100644 --- a/trunk/drivers/net/pcmcia/fmvj18x_cs.c +++ b/trunk/drivers/net/pcmcia/fmvj18x_cs.c @@ -72,6 +72,13 @@ MODULE_LICENSE("GPL"); /* 0:4KB*2 TX buffer else:8KB*2 TX buffer */ 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 /*====================================================================*/ /* @@ -238,7 +245,7 @@ static int fmvj18x_probe(struct pcmcia_device *link) local_info_t *lp; struct net_device *dev; - dev_dbg(&link->dev, "fmvj18x_attach()\n"); + DEBUG(0, "fmvj18x_attach()\n"); /* Make up a FMVJ18x specific data structure */ dev = alloc_etherdev(sizeof(local_info_t)); @@ -255,8 +262,10 @@ static int fmvj18x_probe(struct pcmcia_device *link) link->io.IOAddrLines = 5; /* Interrupt setup */ - 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 = &fjn_interrupt; + link->irq.Instance = dev; /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; @@ -276,7 +285,7 @@ static void fmvj18x_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "fmvj18x_detach\n"); + DEBUG(0, "fmvj18x_detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -288,6 +297,9 @@ 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) { int i, ret; @@ -329,38 +341,33 @@ static int ungermann_try_io_port(struct pcmcia_device *link) 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) { struct net_device *dev = link->priv; local_info_t *lp = netdev_priv(dev); - int i, ret; + tuple_t tuple; + cisparse_t parse; + u_short buf[32]; + int i, last_fn = 0, last_ret = 0, ret; unsigned int ioaddr; cardtype_t cardtype; char *card_name = "unknown"; - u8 *buf; - size_t len; - u_char buggybuf[32]; - - dev_dbg(&link->dev, "fmvj18x_config\n"); + u_char *node_id; - len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf); - kfree(buf); + DEBUG(0, "fmvj18x_config(0x%p)\n", link); - if (len) { + tuple.TupleData = (u_char *)buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_FUNCE; + tuple.TupleOffset = 0; + if (pcmcia_get_first_tuple(link, &tuple) == 0) { /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ - ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL); - if (ret != 0) - goto failed; - + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); + link->conf.ConfigIndex = parse.cftable_entry.index; switch (link->manf_id) { case MANFID_TDK: cardtype = TDK; @@ -426,24 +433,17 @@ static int fmvj18x_config(struct pcmcia_device *link) if (link->io.NumPorts2 != 0) { link->irq.Attributes = - IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; ret = mfc_try_io_port(link); - if (ret != 0) goto failed; + if (ret != 0) goto cs_failed; } else if (cardtype == UNGERMANN) { ret = ungermann_try_io_port(link); - if (ret != 0) goto failed; + if (ret != 0) goto cs_failed; } else { - ret = pcmcia_request_io(link, &link->io); - if (ret) - goto failed; + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); } - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - 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->base_addr = link->io.BasePort1; @@ -474,21 +474,21 @@ static int fmvj18x_config(struct pcmcia_device *link) case CONTEC: case NEC: 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) { + /* MBH10304's CIS_FUNCE is corrupted */ + node_id = &(tuple.TupleData[5]); card_name = "FMV-J182"; - - len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf); - if (len < 11) { - kfree(buf); - goto failed; - } - /* 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; + while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) { + CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + } + node_id = &(tuple.TupleData[2]); if( cardtype == TDK ) { card_name = "TDK LAK-CD021"; } else if( cardtype == LA501 ) { @@ -501,6 +501,9 @@ static int fmvj18x_config(struct pcmcia_device *link) card_name = "C-NET(PC)C"; } } + /* Read MACID from CIS */ + for (i = 0; i < 6; i++) + dev->dev_addr[i] = node_id[i]; break; case UNGERMANN: /* Read MACID from register */ @@ -510,12 +513,12 @@ static int fmvj18x_config(struct pcmcia_device *link) break; case XXX10304: /* Read MACID from Buggy CIS */ - if (fmvj18x_get_hwinfo(link, buggybuf) == -1) { + if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) { printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n"); goto failed; } for (i = 0 ; i < 6; i++) { - dev->dev_addr[i] = buggybuf[i]; + dev->dev_addr[i] = tuple.TupleData[i]; } card_name = "FMV-J182"; break; @@ -530,7 +533,7 @@ static int fmvj18x_config(struct pcmcia_device *link) lp->cardtype = cardtype; link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); @@ -548,6 +551,9 @@ static int fmvj18x_config(struct pcmcia_device *link) return 0; +cs_failed: + /* All Card Services errors end up here */ + cs_error(link, last_fn, last_ret); failed: fmvj18x_release(link); return -ENODEV; @@ -565,14 +571,16 @@ 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.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(link, &req, &link->win); - if (i != 0) + i = pcmcia_request_window(&link, &req, &link->win); + if (i != 0) { + cs_error(link, RequestWindow, i); return -1; + } base = ioremap(req.Base, req.Size); mem.Page = 0; mem.CardOffset = 0; - pcmcia_map_mem_page(link, link->win, &mem); + pcmcia_map_mem_page(link->win, &mem); /* * MBH10304 CISTPL_FUNCE_LAN_NODE_ID format @@ -597,7 +605,9 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) } iounmap(base); - j = pcmcia_release_window(link, link->win); + j = pcmcia_release_window(link->win); + if (j != 0) + cs_error(link, ReleaseWindow, j); return (i != 0x200) ? 0 : -1; } /* fmvj18x_get_hwinfo */ @@ -616,9 +626,11 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(link, &req, &link->win); - if (i != 0) + i = pcmcia_request_window(&link, &req, &link->win); + if (i != 0) { + cs_error(link, RequestWindow, i); return -1; + } lp->base = ioremap(req.Base, req.Size); if (lp->base == NULL) { @@ -628,10 +640,11 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) mem.Page = 0; mem.CardOffset = 0; - i = pcmcia_map_mem_page(link, link->win, &mem); + i = pcmcia_map_mem_page(link->win, &mem); if (i != 0) { iounmap(lp->base); lp->base = NULL; + cs_error(link, MapMemPage, i); return -1; } @@ -658,13 +671,15 @@ static void fmvj18x_release(struct pcmcia_device *link) u_char __iomem *tmp; int j; - dev_dbg(&link->dev, "fmvj18x_release\n"); + DEBUG(0, "fmvj18x_release(0x%p)\n", link); if (lp->base != NULL) { tmp = lp->base; lp->base = NULL; /* set NULL before iounmap */ iounmap(tmp); - j = pcmcia_release_window(link, link->win); + j = pcmcia_release_window(link->win); + if (j != 0) + cs_error(link, ReleaseWindow, j); } pcmcia_disable_device(link); @@ -773,8 +788,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id) outb(tx_stat, ioaddr + TX_STATUS); outb(rx_stat, ioaddr + RX_STATUS); - pr_debug("%s: interrupt, rx_status %02x.\n", dev->name, rx_stat); - pr_debug(" tx_status %02x.\n", tx_stat); + DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat); + DEBUG(4, " tx_status %02x.\n", tx_stat); if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { /* there is packet(s) in rx buffer */ @@ -794,8 +809,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id) } netif_wake_queue(dev); } - pr_debug("%s: exiting interrupt,\n", dev->name); - pr_debug(" tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat); + DEBUG(4, "%s: exiting interrupt,\n", dev->name); + DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat); outb(D_TX_INTR, ioaddr + TX_INTR); outb(D_RX_INTR, ioaddr + RX_INTR); @@ -867,7 +882,7 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb, return NETDEV_TX_BUSY; } - pr_debug("%s: Transmitting a packet of length %lu.\n", + DEBUG(4, "%s: Transmitting a packet of length %lu.\n", dev->name, (unsigned long)skb->len); dev->stats.tx_bytes += skb->len; @@ -922,7 +937,7 @@ static void fjn_reset(struct net_device *dev) unsigned int ioaddr = dev->base_addr; int i; - pr_debug("fjn_reset(%s) called.\n",dev->name); + DEBUG(4, "fjn_reset(%s) called.\n",dev->name); /* Reset controller */ if( sram_config == 0 ) @@ -1000,13 +1015,13 @@ static void fjn_rx(struct net_device *dev) unsigned int ioaddr = dev->base_addr; int boguscount = 10; /* 5 -> 10: by agy 19940922 */ - pr_debug("%s: in rx_packet(), rx_status %02x.\n", + DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n", dev->name, inb(ioaddr + RX_STATUS)); while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { u_short status = inw(ioaddr + DATAPORT); - pr_debug("%s: Rxing packet mode %02x status %04x.\n", + DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n", dev->name, inb(ioaddr + RX_MODE), status); #ifndef final_version if (status == 0) { @@ -1046,14 +1061,16 @@ static void fjn_rx(struct net_device *dev) (pkt_len + 1) >> 1); skb->protocol = eth_type_trans(skb, dev); - { +#ifdef PCMCIA_DEBUG + if (pc_debug > 5) { int i; - pr_debug("%s: Rxed packet of length %d: ", - dev->name, pkt_len); + printk(KERN_DEBUG "%s: Rxed packet of length %d: ", + dev->name, pkt_len); for (i = 0; i < 14; i++) - pr_debug(" %02x", skb->data[i]); - pr_debug(".\n"); + printk(" %02x", skb->data[i]); + printk(".\n"); } +#endif netif_rx(skb); dev->stats.rx_packets++; @@ -1077,7 +1094,7 @@ static void fjn_rx(struct net_device *dev) } if (i > 0) - pr_debug("%s: Exint Rx packet with mode %02x after " + DEBUG(5, "%s: Exint Rx packet with mode %02x after " "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i); } */ @@ -1095,8 +1112,24 @@ static void netdev_get_drvinfo(struct net_device *dev, 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 = { .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){ @@ -1108,7 +1141,7 @@ static int fjn_open(struct net_device *dev) struct local_info_t *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; - pr_debug("fjn_open('%s').\n", dev->name); + DEBUG(4, "fjn_open('%s').\n", dev->name); if (!pcmcia_dev_present(link)) return -ENODEV; @@ -1134,7 +1167,7 @@ static int fjn_close(struct net_device *dev) struct pcmcia_device *link = lp->p_dev; unsigned int ioaddr = dev->base_addr; - pr_debug("fjn_close('%s').\n", dev->name); + DEBUG(4, "fjn_close('%s').\n", dev->name); lp->open_time = 0; netif_stop_queue(dev); diff --git a/trunk/drivers/net/pcmcia/ibmtr_cs.c b/trunk/drivers/net/pcmcia/ibmtr_cs.c index 37f4a6fdc3ef..06618af1a468 100644 --- a/trunk/drivers/net/pcmcia/ibmtr_cs.c +++ b/trunk/drivers/net/pcmcia/ibmtr_cs.c @@ -69,6 +69,17 @@ #define PCMCIA #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 /*====================================================================*/ @@ -119,12 +130,6 @@ static const struct ethtool_ops netdev_ethtool_ops = { .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 @@ -138,7 +143,7 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) ibmtr_dev_t *info; struct net_device *dev; - dev_dbg(&link->dev, "ibmtr_attach()\n"); + DEBUG(0, "ibmtr_attach()\n"); /* Create new token-ring device */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -156,13 +161,14 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 4; link->io.IOAddrLines = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Handler = ibmtr_interrupt; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; + link->irq.Handler = &tok_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; - info->dev = dev; + link->irq.Instance = info->dev = dev; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); @@ -184,7 +190,7 @@ static void ibmtr_detach(struct pcmcia_device *link) struct net_device *dev = info->dev; struct tok_info *ti = netdev_priv(dev); - dev_dbg(&link->dev, "ibmtr_detach\n"); + DEBUG(0, "ibmtr_detach(0x%p)\n", link); /* * When the card removal interrupt hits tok_interrupt(), @@ -211,6 +217,9 @@ 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) { ibmtr_dev_t *info = link->priv; @@ -218,9 +227,9 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) struct tok_info *ti = netdev_priv(dev); win_req_t req; memreq_t mem; - int i, ret; + int i, last_ret, last_fn; - dev_dbg(&link->dev, "ibmtr_config\n"); + DEBUG(0, "ibmtr_config(0x%p)\n", link); link->conf.ConfigIndex = 0x61; @@ -232,15 +241,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) if (i != 0) { /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ link->io.BasePort1 = 0xA24; - ret = pcmcia_request_io(link, &link->io); - if (ret) - goto failed; + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); } dev->base_addr = link->io.BasePort1; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); dev->irq = link->irq.AssignedIRQ; ti->irq = link->irq.AssignedIRQ; ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); @@ -251,15 +256,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) req.Base = 0; req.Size = 0x2000; req.AccessSpeed = 250; - ret = pcmcia_request_window(link, &req, &link->win); - if (ret) - goto failed; + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = mmiobase; mem.Page = 0; - ret = pcmcia_map_mem_page(link, link->win, &mem); - if (ret) - goto failed; + CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); ti->mmio = ioremap(req.Base, req.Size); /* Allocate the SRAM memory window */ @@ -268,23 +269,17 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) req.Base = 0; req.Size = sramsize * 1024; req.AccessSpeed = 250; - ret = pcmcia_request_window(link, &req, &info->sram_win_handle); - if (ret) - goto failed; + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle)); mem.CardOffset = srambase; mem.Page = 0; - ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem); - if (ret) - goto failed; + CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem)); ti->sram_base = mem.CardOffset >> 12; ti->sram_virt = ioremap(req.Base, req.Size); ti->sram_phys = req.Base; - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* Set up the Token-Ring Controller Configuration Register and turn on the card. Check the "Local Area Network Credit Card @@ -292,7 +287,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) ibmtr_hw_setup(dev, mmiobase); link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = ibmtr_probe_card(dev); if (i != 0) { @@ -310,6 +305,8 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) dev->dev_addr); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: ibmtr_release(link); return -ENODEV; @@ -328,12 +325,12 @@ static void ibmtr_release(struct pcmcia_device *link) ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; - dev_dbg(&link->dev, "ibmtr_release\n"); + DEBUG(0, "ibmtr_release(0x%p)\n", link); if (link->win) { struct tok_info *ti = netdev_priv(dev); iounmap(ti->mmio); - pcmcia_release_window(link, info->sram_win_handle); + pcmcia_release_window(info->sram_win_handle); } pcmcia_disable_device(link); } diff --git a/trunk/drivers/net/pcmcia/nmclan_cs.c b/trunk/drivers/net/pcmcia/nmclan_cs.c index dae5ef6b2609..5ed6339c52bc 100644 --- a/trunk/drivers/net/pcmcia/nmclan_cs.c +++ b/trunk/drivers/net/pcmcia/nmclan_cs.c @@ -381,6 +381,13 @@ typedef struct _mace_private { 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[]={ "Auto", "10baseT", "BNC", }; @@ -399,6 +406,12 @@ MODULE_LICENSE("GPL"); /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */ 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 @@ -449,7 +462,8 @@ static int nmclan_probe(struct pcmcia_device *link) mace_private *lp; struct net_device *dev; - dev_dbg(&link->dev, "nmclan_attach()\n"); + DEBUG(0, "nmclan_attach()\n"); + DEBUG(1, "%s\n", rcsid); /* Create new ethernet device */ dev = alloc_etherdev(sizeof(mace_private)); @@ -463,8 +477,10 @@ static int nmclan_probe(struct pcmcia_device *link) link->io.NumPorts1 = 32; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 5; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = &mace_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; @@ -491,7 +507,7 @@ static void nmclan_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "nmclan_detach\n"); + DEBUG(0, "nmclan_detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -638,40 +654,37 @@ nmclan_config 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) { struct net_device *dev = link->priv; mace_private *lp = netdev_priv(dev); - u8 *buf; - size_t len; - int i, ret; + tuple_t tuple; + u_char buf[64]; + int i, last_ret, last_fn; unsigned int ioaddr; - 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; + DEBUG(0, "nmclan_config(0x%p)\n", link); + 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->base_addr = link->io.BasePort1; ioaddr = dev->base_addr; /* Read the ethernet address from the CIS. */ - len = pcmcia_get_tuple(link, 0x80, &buf); - if (!buf || len < ETHER_ADDR_LEN) { - kfree(buf); - goto failed; - } - memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN); - kfree(buf); + tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */; + tuple.TupleData = buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); /* Verify configuration by reading the MACE ID. */ { @@ -680,7 +693,7 @@ static int nmclan_config(struct pcmcia_device *link) sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL); sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH); if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) { - dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n", + DEBUG(0, "nmclan_cs configured: mace id=%x %x\n", sig[0], sig[1]); } else { printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" @@ -699,7 +712,7 @@ static int nmclan_config(struct pcmcia_device *link) printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); link->dev_node = &lp->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if (i != 0) { @@ -716,6 +729,8 @@ static int nmclan_config(struct pcmcia_device *link) dev->dev_addr); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: nmclan_release(link); return -ENODEV; @@ -729,7 +744,7 @@ nmclan_release ---------------------------------------------------------------------------- */ static void nmclan_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "nmclan_release\n"); + DEBUG(0, "nmclan_release(0x%p)\n", link); pcmcia_disable_device(link); } @@ -780,7 +795,7 @@ static void nmclan_reset(struct net_device *dev) /* Reset Xilinx */ reg.Action = CS_WRITE; reg.Offset = CISREG_COR; - dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n", + DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n", OrigCorValue); reg.Value = COR_SOFT_RESET; pcmcia_access_configuration_register(link, ®); @@ -857,7 +872,7 @@ static int mace_close(struct net_device *dev) mace_private *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; - dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name); + DEBUG(2, "%s: shutting down ethercard.\n", dev->name); /* Mask off all interrupts from the MACE chip. */ outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR); @@ -876,8 +891,24 @@ static void netdev_get_drvinfo(struct net_device *dev, 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 = { .get_drvinfo = netdev_get_drvinfo, +#ifdef PCMCIA_DEBUG + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, +#endif /* PCMCIA_DEBUG */ }; /* ---------------------------------------------------------------------------- @@ -915,7 +946,7 @@ static netdev_tx_t mace_start_xmit(struct sk_buff *skb, netif_stop_queue(dev); - pr_debug("%s: mace_start_xmit(length = %ld) called.\n", + DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n", dev->name, (long)skb->len); #if (!TX_INTERRUPTABLE) @@ -977,7 +1008,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) int IntrCnt = MACE_MAX_IR_ITERATIONS; if (dev == NULL) { - pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n", + DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n", irq); return IRQ_NONE; } @@ -1000,7 +1031,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) } if (!netif_device_present(dev)) { - pr_debug("%s: interrupt from dead card\n", dev->name); + DEBUG(2, "%s: interrupt from dead card\n", dev->name); return IRQ_NONE; } @@ -1008,7 +1039,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) /* WARNING: MACE_IR is a READ/CLEAR port! */ status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR); - pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status); + DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status); if (status & MACE_IR_RCVINT) { mace_rx(dev, MACE_MAX_RX_ITERATIONS); @@ -1127,7 +1158,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt) ) { rx_status = inw(ioaddr + AM2150_RCV); - pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status" + DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status" " 0x%X.\n", dev->name, rx_framecnt, rx_status); if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */ @@ -1154,7 +1185,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt) lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV); /* rcv collision count */ - pr_debug(" receiving packet size 0x%X rx_status" + DEBUG(3, " receiving packet size 0x%X rx_status" " 0x%X.\n", pkt_len, rx_status); skb = dev_alloc_skb(pkt_len+2); @@ -1173,7 +1204,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt) outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */ continue; } else { - pr_debug("%s: couldn't allocate a sk_buff of size" + DEBUG(1, "%s: couldn't allocate a sk_buff of size" " %d.\n", dev->name, pkt_len); lp->linux_stats.rx_dropped++; } @@ -1189,28 +1220,28 @@ pr_linux_stats ---------------------------------------------------------------------------- */ static void pr_linux_stats(struct net_device_stats *pstats) { - pr_debug("pr_linux_stats\n"); - pr_debug(" rx_packets=%-7ld tx_packets=%ld\n", + DEBUG(2, "pr_linux_stats\n"); + DEBUG(2, " rx_packets=%-7ld tx_packets=%ld\n", (long)pstats->rx_packets, (long)pstats->tx_packets); - pr_debug(" rx_errors=%-7ld tx_errors=%ld\n", + DEBUG(2, " rx_errors=%-7ld tx_errors=%ld\n", (long)pstats->rx_errors, (long)pstats->tx_errors); - pr_debug(" rx_dropped=%-7ld tx_dropped=%ld\n", + DEBUG(2, " rx_dropped=%-7ld tx_dropped=%ld\n", (long)pstats->rx_dropped, (long)pstats->tx_dropped); - pr_debug(" multicast=%-7ld collisions=%ld\n", + DEBUG(2, " multicast=%-7ld collisions=%ld\n", (long)pstats->multicast, (long)pstats->collisions); - pr_debug(" rx_length_errors=%-7ld rx_over_errors=%ld\n", + DEBUG(2, " rx_length_errors=%-7ld rx_over_errors=%ld\n", (long)pstats->rx_length_errors, (long)pstats->rx_over_errors); - pr_debug(" rx_crc_errors=%-7ld rx_frame_errors=%ld\n", + DEBUG(2, " rx_crc_errors=%-7ld rx_frame_errors=%ld\n", (long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors); - pr_debug(" rx_fifo_errors=%-7ld rx_missed_errors=%ld\n", + DEBUG(2, " rx_fifo_errors=%-7ld rx_missed_errors=%ld\n", (long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors); - pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n", + DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n", (long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors); - pr_debug(" tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n", + DEBUG(2, " tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n", (long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors); - pr_debug(" tx_window_errors=%ld\n", + DEBUG(2, " tx_window_errors=%ld\n", (long)pstats->tx_window_errors); } /* pr_linux_stats */ @@ -1219,48 +1250,48 @@ pr_mace_stats ---------------------------------------------------------------------------- */ static void pr_mace_stats(mace_statistics *pstats) { - pr_debug("pr_mace_stats\n"); + DEBUG(2, "pr_mace_stats\n"); - pr_debug(" xmtsv=%-7d uflo=%d\n", + DEBUG(2, " xmtsv=%-7d uflo=%d\n", pstats->xmtsv, pstats->uflo); - pr_debug(" lcol=%-7d more=%d\n", + DEBUG(2, " lcol=%-7d more=%d\n", pstats->lcol, pstats->more); - pr_debug(" one=%-7d defer=%d\n", + DEBUG(2, " one=%-7d defer=%d\n", pstats->one, pstats->defer); - pr_debug(" lcar=%-7d rtry=%d\n", + DEBUG(2, " lcar=%-7d rtry=%d\n", pstats->lcar, pstats->rtry); /* MACE_XMTRC */ - pr_debug(" exdef=%-7d xmtrc=%d\n", + DEBUG(2, " exdef=%-7d xmtrc=%d\n", pstats->exdef, pstats->xmtrc); /* RFS1--Receive Status (RCVSTS) */ - pr_debug(" oflo=%-7d clsn=%d\n", + DEBUG(2, " oflo=%-7d clsn=%d\n", pstats->oflo, pstats->clsn); - pr_debug(" fram=%-7d fcs=%d\n", + DEBUG(2, " fram=%-7d fcs=%d\n", pstats->fram, pstats->fcs); /* RFS2--Runt Packet Count (RNTPC) */ /* RFS3--Receive Collision Count (RCVCC) */ - pr_debug(" rfs_rntpc=%-7d rfs_rcvcc=%d\n", + DEBUG(2, " rfs_rntpc=%-7d rfs_rcvcc=%d\n", pstats->rfs_rntpc, pstats->rfs_rcvcc); /* MACE_IR */ - pr_debug(" jab=%-7d babl=%d\n", + DEBUG(2, " jab=%-7d babl=%d\n", pstats->jab, pstats->babl); - pr_debug(" cerr=%-7d rcvcco=%d\n", + DEBUG(2, " cerr=%-7d rcvcco=%d\n", pstats->cerr, pstats->rcvcco); - pr_debug(" rntpco=%-7d mpco=%d\n", + DEBUG(2, " rntpco=%-7d mpco=%d\n", pstats->rntpco, pstats->mpco); /* MACE_MPC */ - pr_debug(" mpc=%d\n", pstats->mpc); + DEBUG(2, " mpc=%d\n", pstats->mpc); /* MACE_RNTPC */ - pr_debug(" rntpc=%d\n", pstats->rntpc); + DEBUG(2, " rntpc=%d\n", pstats->rntpc); /* MACE_RCVCC */ - pr_debug(" rcvcc=%d\n", pstats->rcvcc); + DEBUG(2, " rcvcc=%d\n", pstats->rcvcc); } /* pr_mace_stats */ @@ -1329,7 +1360,7 @@ static struct net_device_stats *mace_get_stats(struct net_device *dev) update_stats(dev->base_addr, dev); - pr_debug("%s: updating the statistics.\n", dev->name); + DEBUG(1, "%s: updating the statistics.\n", dev->name); pr_linux_stats(&lp->linux_stats); pr_mace_stats(&lp->mace_stats); @@ -1396,7 +1427,7 @@ static void BuildLAF(int *ladrf, int *adr) ladrf[byte] |= (1 << (hashcode & 7)); #ifdef PCMCIA_DEBUG - if (0) + if (pc_debug > 2) printk(KERN_DEBUG " adr =%pM\n", adr); printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode); for (i = 0; i < 8; i++) @@ -1423,12 +1454,12 @@ static void restore_multicast_list(struct net_device *dev) unsigned int ioaddr = dev->base_addr; int i; - pr_debug("%s: restoring Rx mode to %d addresses.\n", + DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name, num_addrs); if (num_addrs > 0) { - pr_debug("Attempt to restore multicast list detected.\n"); + DEBUG(1, "Attempt to restore multicast list detected.\n"); mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR); /* Poll ADDRCHG bit */ @@ -1480,11 +1511,11 @@ static void set_multicast_list(struct net_device *dev) struct dev_mc_list *dmi = dev->mc_list; #ifdef PCMCIA_DEBUG - { + if (pc_debug > 1) { static int old; if (dev->mc_count != old) { old = dev->mc_count; - pr_debug("%s: setting Rx mode to %d addresses.\n", + DEBUG(0, "%s: setting Rx mode to %d addresses.\n", dev->name, old); } } @@ -1515,7 +1546,7 @@ static void restore_multicast_list(struct net_device *dev) unsigned int ioaddr = dev->base_addr; mace_private *lp = netdev_priv(dev); - pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name, + DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name, lp->multicast_num_addrs); if (dev->flags & IFF_PROMISC) { @@ -1536,11 +1567,11 @@ static void set_multicast_list(struct net_device *dev) mace_private *lp = netdev_priv(dev); #ifdef PCMCIA_DEBUG - { + if (pc_debug > 1) { static int old; if (dev->mc_count != old) { old = dev->mc_count; - pr_debug("%s: setting Rx mode to %d addresses.\n", + DEBUG(0, "%s: setting Rx mode to %d addresses.\n", dev->name, old); } } diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index cbe462ed221f..94c9ad2746bc 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -71,6 +71,15 @@ 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 /*====================================================================*/ @@ -256,7 +265,7 @@ static int pcnet_probe(struct pcmcia_device *link) pcnet_dev_t *info; struct net_device *dev; - dev_dbg(&link->dev, "pcnet_attach()\n"); + DEBUG(0, "pcnet_attach()\n"); /* Create new ethernet device */ dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); @@ -266,6 +275,7 @@ static int pcnet_probe(struct pcmcia_device *link) link->priv = dev; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -287,7 +297,7 @@ static void pcnet_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "pcnet_detach\n"); + DEBUG(0, "pcnet_detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -316,15 +326,17 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = 0; req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(link, &req, &link->win); - if (i != 0) + i = pcmcia_request_window(&link, &req, &link->win); + if (i != 0) { + cs_error(link, RequestWindow, i); return NULL; + } virt = ioremap(req.Base, req.Size); mem.Page = 0; for (i = 0; i < NR_INFO; i++) { mem.CardOffset = hw_info[i].offset & ~(req.Size-1); - pcmcia_map_mem_page(link, link->win, &mem); + pcmcia_map_mem_page(link->win, &mem); base = &virt[hw_info[i].offset & (req.Size-1)]; if ((readb(base+0) == hw_info[i].a0) && (readb(base+2) == hw_info[i].a1) && @@ -336,7 +348,9 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) } iounmap(virt); - j = pcmcia_release_window(link, link->win); + j = pcmcia_release_window(link->win); + if (j != 0) + cs_error(link, ReleaseWindow, j); return (i < NR_INFO) ? hw_info+i : NULL; } /* get_hwinfo */ @@ -481,6 +495,9 @@ 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) { int j, ret; @@ -550,19 +567,19 @@ static int pcnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); - int ret, start_pg, stop_pg, cm_offset; + int last_ret, last_fn, start_pg, stop_pg, cm_offset; int has_shmem = 0; hw_info_t *local_hw_info; - dev_dbg(&link->dev, "pcnet_config\n"); + DEBUG(0, "pcnet_config(0x%p)\n", link); - ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); - if (ret) + last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); + if (last_ret) { + cs_error(link, RequestIO, last_ret); goto failed; + } - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); if (link->io.NumPorts2 == 8) { link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -572,9 +589,7 @@ static int pcnet_config(struct pcmcia_device *link) (link->card_id == PRODID_IBM_HOME_AND_AWAY)) link->conf.ConfigIndex |= 0x10; - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; if (info->flags & HAS_MISC_REG) { @@ -645,7 +660,7 @@ static int pcnet_config(struct pcmcia_device *link) mii_phy_probe(dev); link->dev_node = &info->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); @@ -672,6 +687,8 @@ static int pcnet_config(struct pcmcia_device *link) printk(" hw_addr %pM\n", dev->dev_addr); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: pcnet_release(link); return -ENODEV; @@ -689,7 +706,7 @@ static void pcnet_release(struct pcmcia_device *link) { pcnet_dev_t *info = PRIV(link->priv); - dev_dbg(&link->dev, "pcnet_release\n"); + DEBUG(0, "pcnet_release(0x%p)\n", link); if (info->flags & USE_SHMEM) iounmap(info->base); @@ -943,7 +960,7 @@ static void mii_phy_probe(struct net_device *dev) phyid = tmp << 16; phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2); phyid &= MII_PHYID_REV_MASK; - pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid); + DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid); if (phyid == AM79C9XX_HOME_PHY) { info->pna_phy = i; } else if (phyid != AM79C9XX_ETH_PHY) { @@ -959,7 +976,7 @@ static int pcnet_open(struct net_device *dev) struct pcmcia_device *link = info->p_dev; unsigned int nic_base = dev->base_addr; - dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name); + DEBUG(2, "pcnet_open('%s')\n", dev->name); if (!pcmcia_dev_present(link)) return -ENODEV; @@ -991,7 +1008,7 @@ static int pcnet_close(struct net_device *dev) pcnet_dev_t *info = PRIV(dev); struct pcmcia_device *link = info->p_dev; - dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name); + DEBUG(2, "pcnet_close('%s')\n", dev->name); ei_close(dev); free_irq(dev->irq, dev); @@ -1234,8 +1251,10 @@ static void dma_block_input(struct net_device *dev, int count, int xfer_count = count; char *buf = skb->data; +#ifdef PCMCIA_DEBUG if ((ei_debug > 4) && (count != 4)) - pr_debug("%s: [bi=%d]\n", dev->name, count+4); + printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4); +#endif if (ei_status.dmaing) { printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input." "[DMAstat:%1x][irqlock:%1x]\n", @@ -1476,7 +1495,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, pcnet_dev_t *info = PRIV(dev); win_req_t req; memreq_t mem; - int i, window_size, offset, ret; + int i, window_size, offset, last_ret, last_fn; window_size = (stop_pg - start_pg) << 8; if (window_size > 32 * 1024) @@ -1490,17 +1509,13 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, req.Attributes |= WIN_USE_WAIT; req.Base = 0; req.Size = window_size; req.AccessSpeed = mem_speed; - ret = pcmcia_request_window(link, &req, &link->win); - if (ret) - goto failed; + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = (start_pg << 8) + cm_offset; offset = mem.CardOffset % window_size; mem.CardOffset -= offset; mem.Page = 0; - ret = pcmcia_map_mem_page(link, link->win, &mem); - if (ret) - goto failed; + CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); /* Try scribbling on the buffer */ info->base = ioremap(req.Base, window_size); @@ -1512,8 +1527,8 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, pcnet_reset_8390(dev); if (i != (TX_PAGES<<8)) { iounmap(info->base); - pcmcia_release_window(link, link->win); - info->base = NULL; link->win = 0; + pcmcia_release_window(link->win); + info->base = NULL; link->win = NULL; goto failed; } @@ -1534,6 +1549,8 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, info->flags |= USE_SHMEM; return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: return 1; } @@ -1771,6 +1788,7 @@ static int __init init_pcnet_cs(void) static void __exit exit_pcnet_cs(void) { + DEBUG(0, "pcnet_cs: unloading\n"); pcmcia_unregister_driver(&pcnet_driver); } diff --git a/trunk/drivers/net/pcmcia/smc91c92_cs.c b/trunk/drivers/net/pcmcia/smc91c92_cs.c index 9e0da370912e..7bde2cd34c7e 100644 --- a/trunk/drivers/net/pcmcia/smc91c92_cs.c +++ b/trunk/drivers/net/pcmcia/smc91c92_cs.c @@ -79,6 +79,14 @@ MODULE_FIRMWARE(FIRMWARE_NAME); */ 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_VERSION "1.123" @@ -118,6 +126,12 @@ struct smc_private { int rx_ovrn; }; +struct smc_cfg_mem { + tuple_t tuple; + cisparse_t parse; + u_char buf[255]; +}; + /* Special definitions for Megahertz multifunction cards */ #define MEGAHERTZ_ISR 0x0380 @@ -315,7 +329,7 @@ static int smc91c92_probe(struct pcmcia_device *link) struct smc_private *smc; struct net_device *dev; - dev_dbg(&link->dev, "smc91c92_attach()\n"); + DEBUG(0, "smc91c92_attach()\n"); /* Create new ethernet device */ dev = alloc_etherdev(sizeof(struct smc_private)); @@ -329,8 +343,10 @@ static int smc91c92_probe(struct pcmcia_device *link) link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 4; - 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 = &smc_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -361,7 +377,7 @@ static void smc91c92_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "smc91c92_detach\n"); + DEBUG(0, "smc91c92_detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -392,7 +408,34 @@ static int cvt_ascii_address(struct net_device *dev, char *s) 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 @@ -447,14 +490,19 @@ static int mhz_mfc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); + struct smc_cfg_mem *cfg_mem; win_req_t req; memreq_t mem; 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.Status = CCSR_AUDIO_ENA; link->irq.Attributes = - IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; link->io.IOAddrLines = 16; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; @@ -462,80 +510,91 @@ static int mhz_mfc_config(struct pcmcia_device *link) /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) - return -ENODEV; - + goto free_cfg_mem; dev->base_addr = link->io.BasePort1; /* Allocate a memory window, for accessing the ISR */ req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(link, &req, &link->win); + i = pcmcia_request_window(&link, &req, &link->win); if (i != 0) - return -ENODEV; - + goto free_cfg_mem; smc->base = ioremap(req.Base, req.Size); mem.CardOffset = mem.Page = 0; if (smc->manfid == MANFID_MOTOROLA) mem.CardOffset = link->conf.ConfigBase; - i = pcmcia_map_mem_page(link, link->win, &mem); + i = pcmcia_map_mem_page(link->win, &mem); if ((i == 0) && (smc->manfid == MANFID_MEGAHERTZ) && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) mhz_3288_power(link); - return 0; +free_cfg_mem: + 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) { struct net_device *dev = link->priv; - size_t len; - u8 *buf; + struct smc_cfg_mem *cfg_mem; + tuple_t *tuple; + cisparse_t *parse; + u_char *buf, *station_addr; 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 (fourth) string in the Version 1 Version/ID tuple. */ - if ((link->prod_id[3]) && - (cvt_ascii_address(dev, link->prod_id[3]) == 0)) - return 0; - - /* Workarounds for broken cards start here. */ + tuple->DesiredTuple = CISTPL_VERS_1; + if (first_tuple(link, tuple, parse) != 0) { + rc = -1; + goto free_cfg_mem; + } /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ - if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev)) - return 0; + if (next_tuple(link, tuple, parse) != 0) + first_tuple(link, tuple, parse); + 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 */ - rc = -1; - len = pcmcia_get_tuple(link, 0x81, &buf); - if (buf && len >= 13) { - buf[12] = '\0'; - if (cvt_ascii_address(dev, buf)) - rc = 0; + tuple->DesiredTuple = 0x81; + if (pcmcia_get_first_tuple(link, tuple) != 0) { + rc = -1; + goto free_cfg_mem; } - kfree(buf); - - return rc; -}; + 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; +free_cfg_mem: + kfree(cfg_mem); + return rc; +} /*====================================================================== @@ -625,21 +684,58 @@ static int smc_config(struct pcmcia_device *link) return i; } - static int smc_setup(struct pcmcia_device *link) { 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; - /* Check for a LAN function extension tuple */ - if (!pcmcia_get_mac_from_cis(link, dev)) - return 0; + 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 */ + tuple->DesiredTuple = CISTPL_FUNCE; + i = first_tuple(link, tuple, parse); + 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. */ if (link->prod_id[2]) { - if (cvt_ascii_address(dev, link->prod_id[2]) == 0) - return 0; + station_addr = link->prod_id[2]; + if (cvt_ascii_address(dev, station_addr) == 0) { + rc = 0; + goto free_cfg_mem; + } } - return -1; + + rc = -1; +free_cfg_mem: + kfree(cfg_mem); + return rc; } /*====================================================================*/ @@ -653,7 +749,7 @@ static int osi_config(struct pcmcia_device *link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; link->irq.Attributes = - IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; link->io.NumPorts1 = 64; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; @@ -698,31 +794,41 @@ static int osi_load_firmware(struct pcmcia_device *link) return err; } -static int pcmcia_osi_mac(struct pcmcia_device *p_dev, - tuple_t *tuple, - void *priv) +static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) { - struct net_device *dev = priv; - int i; + struct net_device *dev = link->priv; + struct smc_cfg_mem *cfg_mem; + tuple_t *tuple; + u_char *buf; + int i, rc; - 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; -}; + cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); + if (!cfg_mem) + return -1; + tuple = &cfg_mem->tuple; + buf = cfg_mem->buf; -static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) -{ - struct net_device *dev = link->priv; - int rc; + 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 */ - if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev)) - return -1; + tuple->DesiredTuple = 0x90; + i = pcmcia_get_first_tuple(link, tuple); + 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) && (cardid == PRODID_OSITECH_SEVEN)) || @@ -730,17 +836,20 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) (cardid == PRODID_PSION_NET100))) { rc = osi_load_firmware(link); if (rc) - return rc; + goto free_cfg_mem; } else if (manfid == MANFID_OSITECH) { /* Make sure both functions are powered up */ set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR); /* Now, turn on the interrupt for both card functions */ set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR); - dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n", + DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n", inw(link->io.BasePort1 + OSITECH_AUI_PWR), inw(link->io.BasePort1 + OSITECH_RESET_ISR)); } - return 0; + rc = 0; +free_cfg_mem: + kfree(cfg_mem); + return rc; } static int smc91c92_suspend(struct pcmcia_device *link) @@ -850,6 +959,12 @@ 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) { struct net_device *dev = link->priv; @@ -859,7 +974,7 @@ static int smc91c92_config(struct pcmcia_device *link) unsigned int ioaddr; u_long mir; - dev_dbg(&link->dev, "smc91c92_config\n"); + DEBUG(0, "smc91c92_config(0x%p)\n", link); smc->manfid = link->manf_id; smc->cardid = link->card_id; @@ -875,15 +990,12 @@ static int smc91c92_config(struct pcmcia_device *link) } else { i = smc_config(link); } - if (i) - goto config_failed; + CS_EXIT_TEST(i, RequestIO, config_failed); i = pcmcia_request_irq(link, &link->irq); - if (i) - goto config_failed; + CS_EXIT_TEST(i, RequestIRQ, config_failed); i = pcmcia_request_configuration(link, &link->conf); - if (i) - goto config_failed; + CS_EXIT_TEST(i, RequestConfiguration, config_failed); if (smc->manfid == MANFID_MOTOROLA) mot_config(link); @@ -962,7 +1074,7 @@ static int smc91c92_config(struct pcmcia_device *link) } link->dev_node = &smc->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); @@ -988,7 +1100,7 @@ static int smc91c92_config(struct pcmcia_device *link) if (smc->cfg & CFG_MII_SELECT) { if (smc->mii_if.phy_id != -1) { - dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", + DEBUG(0, " MII transceiver at index %d, status %x.\n", smc->mii_if.phy_id, j); } else { printk(KERN_NOTICE " No MII transceivers found!\n"); @@ -998,7 +1110,7 @@ static int smc91c92_config(struct pcmcia_device *link) config_undo: unregister_netdev(dev); -config_failed: +config_failed: /* CS_EXIT_TEST() calls jump to here... */ smc91c92_release(link); return -ENODEV; } /* smc91c92_config */ @@ -1013,7 +1125,7 @@ static int smc91c92_config(struct pcmcia_device *link) static void smc91c92_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "smc91c92_release\n"); + DEBUG(0, "smc91c92_release(0x%p)\n", link); if (link->win) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -1110,10 +1222,10 @@ static int smc_open(struct net_device *dev) struct smc_private *smc = netdev_priv(dev); struct pcmcia_device *link = smc->p_dev; - dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n", - dev->name, dev, inw(dev->base_addr + BANK_SELECT)); #ifdef PCMCIA_DEBUG - smc_dump(dev); + DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n", + dev->name, dev, inw(dev->base_addr + BANK_SELECT)); + if (pc_debug > 1) smc_dump(dev); #endif /* Check that the PCMCIA card is still here. */ @@ -1148,7 +1260,7 @@ static int smc_close(struct net_device *dev) struct pcmcia_device *link = smc->p_dev; unsigned int ioaddr = dev->base_addr; - dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n", + DEBUG(0, "%s: smc_close(), status %4.4x.\n", dev->name, inw(ioaddr + BANK_SELECT)); netif_stop_queue(dev); @@ -1215,7 +1327,7 @@ static void smc_hardware_send_packet(struct net_device * dev) u_char *buf = skb->data; u_int length = skb->len; /* The chip will pad to ethernet min. */ - pr_debug("%s: Trying to xmit packet of length %d.\n", + DEBUG(2, "%s: Trying to xmit packet of length %d.\n", dev->name, length); /* send the packet length: +6 for status word, length, and ctl */ @@ -1270,7 +1382,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb, netif_stop_queue(dev); - pr_debug("%s: smc_start_xmit(length = %d) called," + DEBUG(2, "%s: smc_start_xmit(length = %d) called," " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2)); if (smc->saved_skb) { @@ -1317,7 +1429,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb, } /* Otherwise defer until the Tx-space-allocated interrupt. */ - pr_debug("%s: memory allocation deferred.\n", dev->name); + DEBUG(2, "%s: memory allocation deferred.\n", dev->name); outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT); spin_unlock_irqrestore(&smc->lock, flags); @@ -1382,7 +1494,7 @@ static void smc_eph_irq(struct net_device *dev) SMC_SELECT_BANK(0); ephs = inw(ioaddr + EPH); - pr_debug("%s: Ethernet protocol handler interrupt, status" + DEBUG(2, "%s: Ethernet protocol handler interrupt, status" " %4.4x.\n", dev->name, ephs); /* Could be a counter roll-over warning: update stats. */ card_stats = inw(ioaddr + COUNTER); @@ -1422,7 +1534,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) ioaddr = dev->base_addr; - pr_debug("%s: SMC91c92 interrupt %d at %#x.\n", dev->name, + DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name, irq, ioaddr); spin_lock(&smc->lock); @@ -1431,7 +1543,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) if ((saved_bank & 0xff00) != 0x3300) { /* The device does not exist -- the card could be off-line, or maybe it has been ejected. */ - pr_debug("%s: SMC91c92 interrupt %d for non-existent" + DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent" "/ejected device.\n", dev->name, irq); handled = 0; goto irq_done; @@ -1445,7 +1557,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) do { /* read the status flag, and mask it */ status = inw(ioaddr + INTERRUPT) & 0xff; - pr_debug("%s: Status is %#2.2x (mask %#2.2x).\n", dev->name, + DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name, status, mask); if ((status & mask) == 0) { if (bogus_cnt == INTR_WORK) @@ -1490,7 +1602,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) smc_eph_irq(dev); } while (--bogus_cnt); - pr_debug(" Restoring saved registers mask %2.2x bank %4.4x" + DEBUG(3, " Restoring saved registers mask %2.2x bank %4.4x" " pointer %4.4x.\n", mask, saved_bank, saved_pointer); /* restore state register */ @@ -1498,7 +1610,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) outw(saved_pointer, ioaddr + POINTER); SMC_SELECT_BANK(saved_bank); - pr_debug("%s: Exiting interrupt IRQ%d.\n", dev->name, irq); + DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq); irq_done: @@ -1549,7 +1661,7 @@ static void smc_rx(struct net_device *dev) rx_status = inw(ioaddr + DATA_1); packet_length = inw(ioaddr + DATA_1) & 0x07ff; - pr_debug("%s: Receive status %4.4x length %d.\n", + DEBUG(2, "%s: Receive status %4.4x length %d.\n", dev->name, rx_status, packet_length); if (!(rx_status & RS_ERRORS)) { @@ -1560,7 +1672,7 @@ static void smc_rx(struct net_device *dev) skb = dev_alloc_skb(packet_length+2); if (skb == NULL) { - pr_debug("%s: Low memory, packet dropped.\n", dev->name); + DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name); dev->stats.rx_dropped++; outw(MC_RELEASE, ioaddr + MMU_CMD); return; @@ -1720,7 +1832,7 @@ static void smc_reset(struct net_device *dev) struct smc_private *smc = netdev_priv(dev); int i; - pr_debug("%s: smc91c92 reset called.\n", dev->name); + DEBUG(0, "%s: smc91c92 reset called.\n", dev->name); /* The first interaction must be a write to bring the chip out of sleep mode. */ @@ -2037,6 +2149,18 @@ static u32 smc_get_link(struct net_device *dev) 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) { struct smc_private *smc = netdev_priv(dev); @@ -2060,6 +2184,10 @@ static const struct ethtool_ops ethtool_ops = { .get_settings = smc_get_settings, .set_settings = smc_set_settings, .get_link = smc_get_link, +#ifdef PCMCIA_DEBUG + .get_msglevel = smc_get_msglevel, + .set_msglevel = smc_set_msglevel, +#endif .nway_reset = smc_nway_reset, }; diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index fe504b7f369f..cf8423102538 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -211,6 +211,20 @@ enum xirc_cmd { /* Commands */ 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 KERR_XIRC KERN_ERR "xirc2ps_cs: " @@ -345,7 +359,7 @@ static void xirc_tx_timeout(struct net_device *dev); static void xirc2ps_tx_timeout_task(struct work_struct *work); static void set_addresses(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static int set_card_type(struct pcmcia_device *link); +static int set_card_type(struct pcmcia_device *link, const void *s); static int do_config(struct net_device *dev, struct ifmap *map); static int do_open(struct net_device *dev); static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -357,6 +371,28 @@ static void do_powerdown(struct net_device *dev); static int do_stop(struct net_device *dev); /*=============== 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 GetByte(reg) ((unsigned)inb(ioaddr + (reg))) #define GetWord(reg) ((unsigned)inw(ioaddr + (reg))) @@ -364,7 +400,7 @@ static int do_stop(struct net_device *dev); #define PutWord(reg,value) outw((value), ioaddr+(reg)) /*====== Functions used for debugging =================================*/ -#if 0 /* reading regs may change system status */ +#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */ static void PrintRegisters(struct net_device *dev) { @@ -396,7 +432,7 @@ PrintRegisters(struct net_device *dev) } } } -#endif /* 0 */ +#endif /* PCMCIA_DEBUG */ /*============== MII Management functions ===============*/ @@ -540,7 +576,7 @@ xirc2ps_probe(struct pcmcia_device *link) struct net_device *dev; local_info_t *local; - dev_dbg(&link->dev, "attach()\n"); + DEBUG(0, "attach()\n"); /* Allocate the device structure */ dev = alloc_etherdev(sizeof(local_info_t)); @@ -556,6 +592,7 @@ xirc2ps_probe(struct pcmcia_device *link) link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->irq.Handler = xirc2ps_interrupt; + link->irq.Instance = dev; /* Fill in card specific entries */ dev->netdev_ops = &netdev_ops; @@ -578,7 +615,7 @@ xirc2ps_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "detach\n"); + DEBUG(0, "detach(0x%p)\n", link); if (link->dev_node) unregister_netdev(dev); @@ -607,25 +644,17 @@ xirc2ps_detach(struct pcmcia_device *link) * */ static int -set_card_type(struct pcmcia_device *link) +set_card_type(struct pcmcia_device *link, const void *s) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); - u8 *buf; - unsigned int cisrev, mediaid, prodid; - size_t len; - - 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]; + #ifdef PCMCIA_DEBUG + unsigned cisrev = ((const unsigned char *)s)[2]; + #endif + unsigned mediaid= ((const unsigned char *)s)[3]; + unsigned prodid = ((const unsigned char *)s)[4]; - dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n", + DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n", cisrev, mediaid, prodid); local->mohawk = 0; @@ -732,26 +761,6 @@ 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 * is received, to configure the PCMCIA socket, and to make the @@ -763,21 +772,33 @@ xirc2ps_config(struct pcmcia_device * link) struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); unsigned int ioaddr; - int err; - u8 *buf; - size_t len; + tuple_t tuple; + cisparse_t parse; + int err, i; + u_char buf[64]; + cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; local->dingo_ccr = NULL; - dev_dbg(&link->dev, "config\n"); + DEBUG(0, "config(0x%p)\n", link); + + /* + * 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 */ - if (link->has_manf_id == 0) { + tuple.DesiredTuple = CISTPL_MANFID; + if ((err=first_tuple(link, &tuple, &parse))) { printk(KNOT_XIRC "manfid not found in CIS\n"); goto failure; } - switch (link->manf_id) { + switch(parse.manfid.manf) { case MANFID_XIRCOM: local->manf_str = "Xircom"; break; @@ -796,44 +817,65 @@ xirc2ps_config(struct pcmcia_device * link) break; default: printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n", - (unsigned)link->manf_id); + (unsigned)parse.manfid.manf); goto failure; } - dev_dbg(&link->dev, "found %s card\n", local->manf_str); + DEBUG(0, "found %s card\n", local->manf_str); - if (!set_card_type(link)) { + if (!set_card_type(link, buf)) { printk(KNOT_XIRC "this card is not supported\n"); goto failure; } /* get the ethernet address from the CIS */ - err = pcmcia_get_mac_from_cis(link, dev); - - /* not found: try to get the node-id from tuple 0x89 */ - if (err) { - len = pcmcia_get_tuple(link, 0x89, &buf); - /* data layout looks like tuple 0x22 */ - if (buf && len == 8) { - if (*buf == CISTPL_FUNCE_LAN_NODE_ID) { - int i; - for (i = 2; i < 6; i++) - dev->dev_addr[i] = buf[i+2]; - } else - err = -1; + tuple.DesiredTuple = CISTPL_FUNCE; + for (err = first_tuple(link, &tuple, &parse); !err; + err = next_tuple(link, &tuple, &parse)) { + /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries: + * the first one with a length of zero the second correct - + * so I skip all entries with length 0 */ + if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID + && ((cistpl_lan_node_id_t *)parse.funce.data)->nb) + break; + } + if (err) { /* not found: try to get the node-id from tuple 0x89 */ + tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */ + if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 && + (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) { printk(KNOT_XIRC "node-id not found in CIS\n"); 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.Attributes1 = IO_DATA_PATH_WIDTH_16; + link->irq.Attributes = IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; if (local->modem) { int pass; @@ -874,8 +916,10 @@ xirc2ps_config(struct pcmcia_device * link) goto port_found; } 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; + } } port_found: if (err) @@ -885,15 +929,19 @@ xirc2ps_config(struct pcmcia_device * link) * Now allocate an interrupt line. Note that this does not * 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; + } /**************** * This actually configures the PCMCIA socket -- setting up * 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; + } if (local->dingo) { conf_reg_t reg; @@ -908,13 +956,17 @@ xirc2ps_config(struct pcmcia_device * link) reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_0; 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; + } reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_1; 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; + } /* There is no config entry for the Ethernet part which * is at 0x0800. So we allocate a window into the attribute @@ -923,14 +975,17 @@ xirc2ps_config(struct pcmcia_device * link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 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; - + } local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800; mem.CardOffset = 0x0; mem.Page = 0; - if ((err = pcmcia_map_mem_page(link, link->win, &mem))) + if ((err = pcmcia_map_mem_page(link->win, &mem))) { + cs_error(link, MapMemPage, err); goto config_error; + } /* Setup the CCRs; there are no infos in the CIS about the Ethernet * part. @@ -989,7 +1044,7 @@ xirc2ps_config(struct pcmcia_device * link) do_reset(dev, 1); /* a kludge to make the cem56 work */ link->dev_node = &local->node; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if ((err=register_netdev(dev))) { printk(KNOT_XIRC "register_netdev() failed\n"); @@ -1022,7 +1077,7 @@ xirc2ps_config(struct pcmcia_device * link) static void xirc2ps_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "release\n"); + DEBUG(0, "release(0x%p)\n", link); if (link->win) { struct net_device *dev = link->priv; @@ -1089,7 +1144,7 @@ xirc2ps_interrupt(int irq, void *dev_id) PutByte(XIRCREG_CR, 0); } - pr_debug("%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr); + DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr); saved_page = GetByte(XIRCREG_PR); /* Read the ISR to see whats the cause for the interrupt. @@ -1099,7 +1154,7 @@ xirc2ps_interrupt(int irq, void *dev_id) bytes_rcvd = 0; loop_entry: if (int_status == 0xff) { /* card may be ejected */ - pr_debug("%s: interrupt %d for dead card\n", dev->name, irq); + DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq); goto leave; } eth_status = GetByte(XIRCREG_ESR); @@ -1112,7 +1167,7 @@ xirc2ps_interrupt(int irq, void *dev_id) PutByte(XIRCREG40_TXST0, 0); PutByte(XIRCREG40_TXST1, 0); - pr_debug("%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n", + DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n", dev->name, int_status, eth_status, rx_status, tx_status); /***** receive section ******/ @@ -1123,14 +1178,14 @@ xirc2ps_interrupt(int irq, void *dev_id) /* too many bytes received during this int, drop the rest of the * packets */ dev->stats.rx_dropped++; - pr_debug("%s: RX drop, too much done\n", dev->name); + DEBUG(2, "%s: RX drop, too much done\n", dev->name); } else if (rsr & PktRxOk) { struct sk_buff *skb; pktlen = GetWord(XIRCREG0_RBC); bytes_rcvd += pktlen; - pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen); + DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen); skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */ if (!skb) { @@ -1198,19 +1253,19 @@ xirc2ps_interrupt(int irq, void *dev_id) dev->stats.multicast++; } } else { /* bad packet */ - pr_debug("rsr=%#02x\n", rsr); + DEBUG(5, "rsr=%#02x\n", rsr); } if (rsr & PktTooLong) { dev->stats.rx_frame_errors++; - pr_debug("%s: Packet too long\n", dev->name); + DEBUG(3, "%s: Packet too long\n", dev->name); } if (rsr & CRCErr) { dev->stats.rx_crc_errors++; - pr_debug("%s: CRC error\n", dev->name); + DEBUG(3, "%s: CRC error\n", dev->name); } if (rsr & AlignErr) { dev->stats.rx_fifo_errors++; /* okay ? */ - pr_debug("%s: Alignment error\n", dev->name); + DEBUG(3, "%s: Alignment error\n", dev->name); } /* clear the received/dropped/error packet */ @@ -1222,7 +1277,7 @@ xirc2ps_interrupt(int irq, void *dev_id) if (rx_status & 0x10) { /* Receive overrun */ dev->stats.rx_over_errors++; PutByte(XIRCREG_CR, ClearRxOvrun); - pr_debug("receive overrun cleared\n"); + DEBUG(3, "receive overrun cleared\n"); } /***** transmit section ******/ @@ -1235,13 +1290,13 @@ xirc2ps_interrupt(int irq, void *dev_id) if (nn < n) /* rollover */ dev->stats.tx_packets += 256 - n; else if (n == nn) { /* happens sometimes - don't know why */ - pr_debug("PTR not changed?\n"); + DEBUG(0, "PTR not changed?\n"); } else dev->stats.tx_packets += lp->last_ptr_value - n; netif_wake_queue(dev); } if (tx_status & 0x0002) { /* Execessive collissions */ - pr_debug("tx restarted due to execssive collissions\n"); + DEBUG(0, "tx restarted due to execssive collissions\n"); PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */ } if (tx_status & 0x0040) @@ -1260,14 +1315,14 @@ xirc2ps_interrupt(int irq, void *dev_id) maxrx_bytes = 2000; else if (maxrx_bytes > 22000) maxrx_bytes = 22000; - pr_debug("set maxrx=%u (rcvd=%u ticks=%lu)\n", + DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n", maxrx_bytes, bytes_rcvd, duration); } else if (!duration && maxrx_bytes < 22000) { /* now much faster */ maxrx_bytes += 2000; if (maxrx_bytes > 22000) maxrx_bytes = 22000; - pr_debug("set maxrx=%u\n", maxrx_bytes); + DEBUG(1, "set maxrx=%u\n", maxrx_bytes); } } @@ -1317,7 +1372,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned freespace; unsigned pktlen = skb->len; - pr_debug("do_start_xmit(skb=%p, dev=%p) len=%u\n", + DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n", skb, dev, pktlen); @@ -1343,7 +1398,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev) freespace &= 0x7fff; /* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */ okay = pktlen +2 < freespace; - pr_debug("%s: avail. tx space=%u%s\n", + DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n", dev->name, freespace, okay ? " (okay)":" (not enough)"); if (!okay) { /* not enough space */ return NETDEV_TX_BUSY; /* upper layer may decide to requeue this packet */ @@ -1445,7 +1500,7 @@ do_config(struct net_device *dev, struct ifmap *map) { local_info_t *local = netdev_priv(dev); - pr_debug("do_config(%p)\n", dev); + DEBUG(0, "do_config(%p)\n", dev); if (map->port != 255 && map->port != dev->if_port) { if (map->port > 4) return -EINVAL; @@ -1472,7 +1527,7 @@ do_open(struct net_device *dev) local_info_t *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; - dev_dbg(&link->dev, "do_open(%p)\n", dev); + DEBUG(0, "do_open(%p)\n", dev); /* Check that the PCMCIA card is still here. */ /* Physical device present signature. */ @@ -1506,7 +1561,7 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) unsigned int ioaddr = dev->base_addr; struct mii_ioctl_data *data = if_mii(rq); - pr_debug("%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n", + DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n", dev->name, rq->ifr_ifrn.ifrn_name, cmd, data->phy_id, data->reg_num, data->val_in, data->val_out); @@ -1555,7 +1610,7 @@ do_reset(struct net_device *dev, int full) unsigned int ioaddr = dev->base_addr; unsigned value; - pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full); + DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full); hardreset(dev); PutByte(XIRCREG_CR, SoftReset); /* set */ @@ -1593,8 +1648,8 @@ do_reset(struct net_device *dev, int full) } msleep(40); /* wait 40 msec to let it complete */ - #if 0 - { + #ifdef PCMCIA_DEBUG + if (pc_debug) { SelectPage(0); value = GetByte(XIRCREG_ESR); /* read the ESR */ printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value); @@ -1611,7 +1666,7 @@ do_reset(struct net_device *dev, int full) value |= DisableLinkPulse; PutByte(XIRCREG1_ECR, value); #endif - pr_debug("%s: ECR is: %#02x\n", dev->name, value); + DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value); SelectPage(0x42); PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */ @@ -1789,7 +1844,7 @@ do_powerdown(struct net_device *dev) unsigned int ioaddr = dev->base_addr; - pr_debug("do_powerdown(%p)\n", dev); + DEBUG(0, "do_powerdown(%p)\n", dev); SelectPage(4); PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */ @@ -1803,7 +1858,7 @@ do_stop(struct net_device *dev) local_info_t *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; - dev_dbg(&link->dev, "do_stop(%p)\n", dev); + DEBUG(0, "do_stop(%p)\n", dev); if (!link) return -ENODEV; diff --git a/trunk/drivers/net/wireless/airo_cs.c b/trunk/drivers/net/wireless/airo_cs.c index f6036fb42319..d0593ed9170e 100644 --- a/trunk/drivers/net/wireless/airo_cs.c +++ b/trunk/drivers/net/wireless/airo_cs.c @@ -43,6 +43,21 @@ #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 /*====================================================================*/ @@ -130,10 +145,11 @@ static int airo_probe(struct pcmcia_device *p_dev) { local_info_t *local; - dev_dbg(&p_dev->dev, "airo_attach()\n"); + DEBUG(0, "airo_attach()\n"); /* Interrupt setup */ p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = NULL; /* @@ -168,7 +184,7 @@ static int airo_probe(struct pcmcia_device *p_dev) static void airo_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "airo_detach\n"); + DEBUG(0, "airo_detach(0x%p)\n", link); airo_release(link); @@ -188,6 +204,9 @@ 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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -256,11 +275,11 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev, req->Base = mem->win[0].host_addr; req->Size = mem->win[0].len; 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; map.Page = 0; map.CardOffset = mem->win[0].card_addr; - if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0) + if (pcmcia_map_mem_page(p_dev->win, &map) != 0) return -ENODEV; } /* If we got this far, we're cool! */ @@ -272,11 +291,11 @@ static int airo_config(struct pcmcia_device *link) { local_info_t *dev; win_req_t *req; - int ret; + int last_fn, last_ret; dev = link->priv; - dev_dbg(&link->dev, "airo_config\n"); + DEBUG(0, "airo_config(0x%p)\n", link); req = kzalloc(sizeof(win_req_t), GFP_KERNEL); if (!req) @@ -296,8 +315,8 @@ static int airo_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - ret = pcmcia_loop_config(link, airo_cs_config_check, req); - if (ret) + last_ret = pcmcia_loop_config(link, airo_cs_config_check, req); + if (last_ret) goto failed; /* @@ -305,25 +324,21 @@ static int airo_config(struct pcmcia_device *link) handler to the interrupt, unless the 'Handler' member of the irq structure is initialized. */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (link->conf.Attributes & CONF_ENABLE_IRQ) + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, + pcmcia_request_configuration(link, &link->conf)); ((local_info_t *)link->priv)->eth_dev = init_airo_card(link->irq.AssignedIRQ, - link->io.BasePort1, 1, &link->dev); + link->io.BasePort1, 1, &handle_to_dev(link)); if (!((local_info_t *)link->priv)->eth_dev) - goto failed; + goto cs_failed; /* At this point, the dev_node_t structure(s) need to be @@ -353,6 +368,8 @@ static int airo_config(struct pcmcia_device *link) kfree(req); return 0; + cs_failed: + cs_error(link, last_fn, last_ret); failed: airo_release(link); kfree(req); @@ -369,7 +386,7 @@ static int airo_config(struct pcmcia_device *link) static void airo_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "airo_release\n"); + DEBUG(0, "airo_release(0x%p)\n", link); pcmcia_disable_device(link); } diff --git a/trunk/drivers/net/wireless/atmel_cs.c b/trunk/drivers/net/wireless/atmel_cs.c index 32407911842f..ddaa859c3491 100644 --- a/trunk/drivers/net/wireless/atmel_cs.c +++ b/trunk/drivers/net/wireless/atmel_cs.c @@ -55,6 +55,22 @@ #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 /*====================================================================*/ @@ -139,10 +155,11 @@ static int atmel_probe(struct pcmcia_device *p_dev) { local_info_t *local; - dev_dbg(&p_dev->dev, "atmel_attach()\n"); + DEBUG(0, "atmel_attach()\n"); /* Interrupt setup */ p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = NULL; /* @@ -177,7 +194,7 @@ static int atmel_probe(struct pcmcia_device *p_dev) static void atmel_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "atmel_detach\n"); + DEBUG(0, "atmel_detach(0x%p)\n", link); atmel_release(link); @@ -192,6 +209,9 @@ 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 about the current existance of the card */ static int card_present(void *arg) @@ -255,13 +275,13 @@ static int atmel_config_check(struct pcmcia_device *p_dev, static int atmel_config(struct pcmcia_device *link) { local_info_t *dev; - int ret; + int last_fn, last_ret; struct pcmcia_device_id *did; dev = link->priv; - did = dev_get_drvdata(&link->dev); + did = dev_get_drvdata(&handle_to_dev(link)); - dev_dbg(&link->dev, "atmel_config\n"); + DEBUG(0, "atmel_config(0x%p)\n", link); /* In this loop, we scan the CIS for configuration table entries, @@ -283,36 +303,31 @@ static int atmel_config(struct pcmcia_device *link) handler to the interrupt, unless the 'Handler' member of the irq structure is initialized. */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } + if (link->conf.Attributes & CONF_ENABLE_IRQ) + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if (link->irq.AssignedIRQ == 0) { printk(KERN_ALERT "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config."); - goto failed; + goto cs_failed; } ((local_info_t*)link->priv)->eth_dev = init_atmel_card(link->irq.AssignedIRQ, link->io.BasePort1, did ? did->driver_info : ATMEL_FW_TYPE_NONE, - &link->dev, + &handle_to_dev(link), card_present, link); if (!((local_info_t*)link->priv)->eth_dev) - goto failed; + goto cs_failed; /* @@ -325,6 +340,8 @@ static int atmel_config(struct pcmcia_device *link) return 0; + cs_failed: + cs_error(link, last_fn, last_ret); failed: atmel_release(link); return -ENODEV; @@ -342,7 +359,7 @@ static void atmel_release(struct pcmcia_device *link) { struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; - dev_dbg(&link->dev, "atmel_release\n"); + DEBUG(0, "atmel_release(0x%p)\n", link); if (dev) stop_atmel_card(dev); diff --git a/trunk/drivers/net/wireless/b43/pcmcia.c b/trunk/drivers/net/wireless/b43/pcmcia.c index 984174bc7b0f..6c3a74964ab8 100644 --- a/trunk/drivers/net/wireless/b43/pcmcia.c +++ b/trunk/drivers/net/wireless/b43/pcmcia.c @@ -65,15 +65,35 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) struct ssb_bus *ssb; win_req_t win; memreq_t mem; + tuple_t tuple; + cisparse_t parse; int err = -ENOMEM; int res = 0; + unsigned char buf[64]; ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); if (!ssb) goto out_error; 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.IntType = INT_MEMORY_AND_IO; @@ -87,18 +107,20 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) win.Base = 0; win.Size = SSB_CORE_SIZE; win.AccessSpeed = 250; - res = pcmcia_request_window(dev, &win, &dev->win); + res = pcmcia_request_window(&dev, &win, &dev->win); if (res != 0) goto err_kfree_ssb; mem.CardOffset = 0; mem.Page = 0; - res = pcmcia_map_mem_page(dev, dev->win, &mem); + res = pcmcia_map_mem_page(dev->win, &mem); if (res != 0) goto err_disable; dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + dev->irq.IRQInfo1 = IRQ_LEVEL_ID; dev->irq.Handler = NULL; /* The handler is registered later. */ + dev->irq.Instance = NULL; res = pcmcia_request_irq(dev, &dev->irq); if (res != 0) goto err_disable; diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c index c9640a3e02c9..ad8eab4a639b 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ b/trunk/drivers/net/wireless/hostap/hostap_cs.c @@ -274,6 +274,9 @@ static int sandisk_enable_wireless(struct net_device *dev) conf_reg_t reg; struct hostap_interface *iface = netdev_priv(dev); 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; if (hw_priv->link->io.NumPorts1 < 0x42) { @@ -282,13 +285,28 @@ static int sandisk_enable_wireless(struct net_device *dev) 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) { /* No SanDisk manfid found */ ret = -ENODEV; goto done; } - if (hw_priv->link->socket->functions < 2) { + tuple.DesiredTuple = CISTPL_LONGLINK_MFC; + 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 */ ret = -ENODEV; goto done; @@ -336,6 +354,7 @@ static int sandisk_enable_wireless(struct net_device *dev) udelay(10); done: + kfree(parse); return ret; } @@ -510,6 +529,10 @@ 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 * socket and make the device available to the system */ @@ -601,6 +624,7 @@ static int prism2_config(struct pcmcia_device *link) struct hostap_interface *iface; local_info_t *local; int ret = 1; + int last_fn, last_ret; struct hostap_cs_priv *hw_priv; PDEBUG(DEBUG_FLOW, "prism2_config()\n"); @@ -612,18 +636,19 @@ static int prism2_config(struct pcmcia_device *link) } /* Look for an appropriate configuration table entry in the CIS */ - ret = pcmcia_loop_config(link, prism2_config_check, NULL); - if (ret) { + last_ret = pcmcia_loop_config(link, prism2_config_check, NULL); + if (last_ret) { if (!ignore_cis_vcc) printk(KERN_ERR "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " "ignore_cis_vcc=1 parameter.\n"); + cs_error(link, RequestIO, last_ret); goto failed; } /* Need to allocate net_device before requesting IRQ handler */ dev = prism2_init_local_data(&prism2_pccard_funcs, 0, - &link->dev); + &handle_to_dev(link)); if (dev == NULL) goto failed; link->priv = dev; @@ -641,11 +666,13 @@ static int prism2_config(struct pcmcia_device *link) * irq structure is initialized. */ 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; - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + link->irq.Instance = dev; + CS_CHECK(RequestIRQ, + pcmcia_request_irq(link, &link->irq)); } /* @@ -653,9 +680,8 @@ static int prism2_config(struct pcmcia_device *link) * the I/O windows and the interrupt mapping, and putting the * card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, + pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -688,6 +714,9 @@ static int prism2_config(struct pcmcia_device *link) } return ret; + cs_failed: + cs_error(link, last_fn, last_ret); + failed: kfree(hw_priv); prism2_release((u_long)link); diff --git a/trunk/drivers/net/wireless/libertas/if_cs.c b/trunk/drivers/net/wireless/libertas/if_cs.c index b1d84592b959..62381768f2d5 100644 --- a/trunk/drivers/net/wireless/libertas/if_cs.c +++ b/trunk/drivers/net/wireless/libertas/if_cs.c @@ -590,7 +590,7 @@ static int if_cs_prog_helper(struct if_cs_card *card) /* TODO: make firmware file configurable */ ret = request_firmware(&fw, "libertas_cs_helper.fw", - &card->p_dev->dev); + &handle_to_dev(card->p_dev)); if (ret) { lbs_pr_err("can't load helper firmware\n"); ret = -ENODEV; @@ -663,7 +663,7 @@ static int if_cs_prog_real(struct if_cs_card *card) /* TODO: make firmware file configurable */ ret = request_firmware(&fw, "libertas_cs.fw", - &card->p_dev->dev); + &handle_to_dev(card->p_dev)); if (ret) { lbs_pr_err("can't load firmware\n"); ret = -ENODEV; @@ -793,37 +793,18 @@ static void if_cs_release(struct pcmcia_device *p_dev) * configure the card at this point -- we wait until we receive a card * 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) { int ret = -ENOMEM; unsigned int prod_id; struct lbs_private *priv; 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); @@ -837,15 +818,48 @@ static int if_cs_probe(struct pcmcia_device *p_dev) p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; p_dev->irq.Handler = NULL; + p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; p_dev->conf.Attributes = 0; p_dev->conf.IntType = INT_MEMORY_AND_IO; - if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) { - lbs_pr_err("error in pcmcia_loop_config\n"); + tuple.Attributes = 0; + tuple.TupleData = buf; + 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; + } + + 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 diff --git a/trunk/drivers/net/wireless/netwave_cs.c b/trunk/drivers/net/wireless/netwave_cs.c index e61e6b9440ab..9498b46c99a4 100644 --- a/trunk/drivers/net/wireless/netwave_cs.c +++ b/trunk/drivers/net/wireless/netwave_cs.c @@ -145,6 +145,23 @@ static const unsigned int txConfEUD = 0x10; /* Enable Uni-Data packets */ static const unsigned int txConfKey = 0x02; /* Scramble data packets */ 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 /*====================================================================*/ @@ -366,7 +383,7 @@ static int netwave_probe(struct pcmcia_device *link) struct net_device *dev; netwave_private *priv; - dev_dbg(&link->dev, "netwave_attach()\n"); + DEBUG(0, "netwave_attach()\n"); /* Initialize the struct pcmcia_device structure */ dev = alloc_etherdev(sizeof(netwave_private)); @@ -384,7 +401,8 @@ static int netwave_probe(struct pcmcia_device *link) link->io.IOAddrLines = 5; /* Interrupt setup */ - 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 = &netwave_interrupt; /* General socket configuration */ @@ -403,6 +421,8 @@ static int netwave_probe(struct pcmcia_device *link) dev->watchdog_timeo = TX_TIMEOUT; + link->irq.Instance = dev; + return netwave_pcmcia_config( link); } /* netwave_attach */ @@ -418,7 +438,7 @@ static void netwave_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; - dev_dbg(&link->dev, "netwave_detach\n"); + DEBUG(0, "netwave_detach(0x%p)\n", link); netwave_release(link); @@ -705,15 +725,18 @@ 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) { struct net_device *dev = link->priv; netwave_private *priv = netdev_priv(dev); - int i, j, ret; + int i, j, last_ret, last_fn; win_req_t req; memreq_t mem; u_char __iomem *ramBase = NULL; - dev_dbg(&link->dev, "netwave_pcmcia_config\n"); + DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link); /* * Try allocating IO ports. This tries a few fixed addresses. @@ -726,24 +749,22 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { if (i == 0) break; } - if (i != 0) + if (i != 0) { + cs_error(link, RequestIO, i); goto failed; + } /* * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* * This actually configures the PCMCIA socket -- setting up * the I/O windows and the interrupt mapping. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* * Allocate a 32K memory window. Note that the struct pcmcia_device @@ -751,18 +772,14 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { * device needs several windows, you'll need to keep track of * the handles in your private data structure, dev->priv. */ - dev_dbg(&link->dev, "Setting mem speed of %d\n", mem_speed); + DEBUG(1, "Setting mem speed of %d\n", mem_speed); req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE; req.Base = 0; req.Size = 0x8000; req.AccessSpeed = mem_speed; - ret = pcmcia_request_window(link, &req, &link->win); - if (ret) - goto failed; + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = 0x20000; mem.Page = 0; - ret = pcmcia_map_mem_page(link, link->win, &mem); - if (ret) - goto failed; + CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); /* Store base address of the common window frame */ ramBase = ioremap(req.Base, 0x8000); @@ -770,7 +787,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev) != 0) { printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n"); @@ -801,6 +818,8 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { get_uint16(ramBase + NETWAVE_EREG_ARW+2)); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: netwave_release(link); return -ENODEV; @@ -818,7 +837,7 @@ static void netwave_release(struct pcmcia_device *link) struct net_device *dev = link->priv; netwave_private *priv = netdev_priv(dev); - dev_dbg(&link->dev, "netwave_release\n"); + DEBUG(0, "netwave_release(0x%p)\n", link); pcmcia_disable_device(link); if (link->win) @@ -873,7 +892,7 @@ static void netwave_reset(struct net_device *dev) { u_char __iomem *ramBase = priv->ramBase; unsigned int iobase = dev->base_addr; - pr_debug("netwave_reset: Done with hardware reset\n"); + DEBUG(0, "netwave_reset: Done with hardware reset\n"); priv->timeoutCounter = 0; @@ -969,7 +988,7 @@ static int netwave_hw_xmit(unsigned char* data, int len, dev->stats.tx_bytes += len; - pr_debug("Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n", + DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n", readb(ramBase + NETWAVE_EREG_SPCQ), readb(ramBase + NETWAVE_EREG_SPU), readb(ramBase + NETWAVE_EREG_LIF), @@ -981,7 +1000,7 @@ static int netwave_hw_xmit(unsigned char* data, int len, MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2); DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4); - pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n", + DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n", TxFreeList, MaxData, DataOffset); /* Copy packet to the adapter fragment buffers */ @@ -1069,7 +1088,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) status = inb(iobase + NETWAVE_REG_ASR); if (!pcmcia_dev_present(link)) { - pr_debug("netwave_interrupt: Interrupt with status 0x%x " + DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x " "from removed or suspended card!\n", status); break; } @@ -1113,7 +1132,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) int txStatus; txStatus = readb(ramBase + NETWAVE_EREG_TSER); - pr_debug("Transmit done. TSER = %x id %x\n", + DEBUG(3, "Transmit done. TSER = %x id %x\n", txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1)); if (txStatus & 0x20) { @@ -1137,7 +1156,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) * TxGU and TxNOAP is set. (Those are the only ones * to set TxErr). */ - pr_debug("netwave_interrupt: TxDN with error status %x\n", + DEBUG(3, "netwave_interrupt: TxDN with error status %x\n", txStatus); /* Clear out TxGU, TxNOAP, TxErr and TxTrys */ @@ -1145,7 +1164,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4); ++dev->stats.tx_errors; } - pr_debug("New status is TSER %x ASR %x\n", + DEBUG(3, "New status is TSER %x ASR %x\n", readb(ramBase + NETWAVE_EREG_TSER), inb(iobase + NETWAVE_REG_ASR)); @@ -1153,7 +1172,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) } /* TxBA, this would trigger on all error packets received */ /* if (status & 0x01) { - pr_debug("Transmit buffers available, %x\n", status); + DEBUG(4, "Transmit buffers available, %x\n", status); } */ } @@ -1171,7 +1190,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) */ static void netwave_watchdog(struct net_device *dev) { - pr_debug("%s: netwave_watchdog: watchdog timer expired\n", dev->name); + DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name); netwave_reset(dev); dev->trans_start = jiffies; netif_wake_queue(dev); @@ -1192,7 +1211,7 @@ static int netwave_rx(struct net_device *dev) int i; u_char *ptr; - pr_debug("xinw_rx: Receiving ... \n"); + DEBUG(3, "xinw_rx: Receiving ... \n"); /* Receive max 10 packets for now. */ for (i = 0; i < 10; i++) { @@ -1218,7 +1237,7 @@ static int netwave_rx(struct net_device *dev) skb = dev_alloc_skb(rcvLen+5); if (skb == NULL) { - pr_debug("netwave_rx: Could not allocate an sk_buff of " + DEBUG(1, "netwave_rx: Could not allocate an sk_buff of " "length %d\n", rcvLen); ++dev->stats.rx_dropped; /* Tell the adapter to skip the packet */ @@ -1260,7 +1279,7 @@ static int netwave_rx(struct net_device *dev) wait_WOC(iobase); writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - pr_debug("Packet reception ok\n"); + DEBUG(3, "Packet reception ok\n"); } return 0; } @@ -1269,7 +1288,7 @@ static int netwave_open(struct net_device *dev) { netwave_private *priv = netdev_priv(dev); struct pcmcia_device *link = priv->p_dev; - dev_dbg(&link->dev, "netwave_open: starting.\n"); + DEBUG(1, "netwave_open: starting.\n"); if (!pcmcia_dev_present(link)) return -ENODEV; @@ -1286,7 +1305,7 @@ static int netwave_close(struct net_device *dev) { netwave_private *priv = netdev_priv(dev); struct pcmcia_device *link = priv->p_dev; - dev_dbg(&link->dev, "netwave_close: finishing.\n"); + DEBUG(1, "netwave_close: finishing.\n"); link->open--; netif_stop_queue(dev); @@ -1339,11 +1358,11 @@ static void set_multicast_list(struct net_device *dev) u_char rcvMode = 0; #ifdef PCMCIA_DEBUG - { - xstatic int old; + if (pc_debug > 2) { + static int old; if (old != dev->mc_count) { old = dev->mc_count; - pr_debug("%s: setting Rx mode to %d addresses.\n", + DEBUG(0, "%s: setting Rx mode to %d addresses.\n", dev->name, dev->mc_count); } } diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco/orinoco_cs.c index f27bb8367c98..38c1c9d2abb8 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_cs.c @@ -109,7 +109,7 @@ orinoco_cs_probe(struct pcmcia_device *link) struct orinoco_private *priv; struct orinoco_pccard *card; - priv = alloc_orinocodev(sizeof(*card), &link->dev, + priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link), orinoco_cs_hard_reset, NULL); if (!priv) return -ENOMEM; @@ -120,8 +120,10 @@ orinoco_cs_probe(struct pcmcia_device *link) link->priv = priv; /* Interrupt setup */ - 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 = orinoco_interrupt; + link->irq.Instance = priv; /* General socket configuration defaults can go here. In this * client, we assume very little, and rely on the CIS for @@ -158,6 +160,12 @@ static void orinoco_cs_detach(struct pcmcia_device *link) * 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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -232,7 +240,7 @@ orinoco_cs_config(struct pcmcia_device *link) struct orinoco_private *priv = link->priv; struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; - int ret; + int last_fn, last_ret; void __iomem *mem; /* @@ -249,12 +257,13 @@ orinoco_cs_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL); - if (ret) { + last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL); + if (last_ret) { if (!ignore_cis_vcc) printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " "ignore_cis_vcc=1 parameter.\n"); + cs_error(link, RequestIO, last_ret); goto failed; } @@ -263,16 +272,14 @@ orinoco_cs_config(struct pcmcia_device *link) * a handler to the interrupt, unless the 'Handler' member of * the irq structure is initialized. */ - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets * called. */ mem = ioport_map(link->io.BasePort1, link->io.NumPorts1); if (!mem) - goto failed; + goto cs_failed; hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); @@ -281,9 +288,8 @@ orinoco_cs_config(struct pcmcia_device *link) * the I/O windows and the interrupt mapping, and putting the * card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, + pcmcia_request_configuration(link, &link->conf)); /* Ok, we have the configuration, prepare to register the netdev */ card->node.major = card->node.minor = 0; @@ -309,6 +315,9 @@ orinoco_cs_config(struct pcmcia_device *link) * net_device has been registered */ return 0; + cs_failed: + cs_error(link, last_fn, last_ret); + failed: orinoco_cs_release(link); return -ENODEV; diff --git a/trunk/drivers/net/wireless/orinoco/spectrum_cs.c b/trunk/drivers/net/wireless/orinoco/spectrum_cs.c index 59bda240fdc2..c361310b885d 100644 --- a/trunk/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/trunk/drivers/net/wireless/orinoco/spectrum_cs.c @@ -73,6 +73,9 @@ static void spectrum_cs_release(struct pcmcia_device *link); #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. * If IDLE is 1, stop the firmware, so that it can be safely rewritten. @@ -80,7 +83,7 @@ static void spectrum_cs_release(struct pcmcia_device *link); static int spectrum_reset(struct pcmcia_device *link, int idle) { - int ret; + int last_ret, last_fn; conf_reg_t reg; u_int save_cor; @@ -92,26 +95,23 @@ spectrum_reset(struct pcmcia_device *link, int idle) reg.Function = 0; reg.Action = CS_READ; reg.Offset = CISREG_COR; - ret = pcmcia_access_configuration_register(link, ®); - if (ret) - goto failed; + CS_CHECK(AccessConfigurationRegister, + pcmcia_access_configuration_register(link, ®)); save_cor = reg.Value; /* Soft-Reset card */ reg.Action = CS_WRITE; reg.Offset = CISREG_COR; reg.Value = (save_cor | COR_SOFT_RESET); - ret = pcmcia_access_configuration_register(link, ®); - if (ret) - goto failed; + CS_CHECK(AccessConfigurationRegister, + pcmcia_access_configuration_register(link, ®)); udelay(1000); /* Read CCSR */ reg.Action = CS_READ; reg.Offset = CISREG_CCSR; - ret = pcmcia_access_configuration_register(link, ®); - if (ret) - goto failed; + CS_CHECK(AccessConfigurationRegister, + pcmcia_access_configuration_register(link, ®)); /* * Start or stop the firmware. Memory width bit should be @@ -120,22 +120,21 @@ spectrum_reset(struct pcmcia_device *link, int idle) reg.Action = CS_WRITE; reg.Offset = CISREG_CCSR; reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16); - ret = pcmcia_access_configuration_register(link, ®); - if (ret) - goto failed; + CS_CHECK(AccessConfigurationRegister, + pcmcia_access_configuration_register(link, ®)); udelay(1000); /* Restore original COR configuration index */ reg.Action = CS_WRITE; reg.Offset = CISREG_COR; reg.Value = (save_cor & ~COR_SOFT_RESET); - ret = pcmcia_access_configuration_register(link, ®); - if (ret) - goto failed; + CS_CHECK(AccessConfigurationRegister, + pcmcia_access_configuration_register(link, ®)); udelay(1000); return 0; -failed: +cs_failed: + cs_error(link, last_fn, last_ret); return -ENODEV; } @@ -182,7 +181,7 @@ spectrum_cs_probe(struct pcmcia_device *link) struct orinoco_private *priv; struct orinoco_pccard *card; - priv = alloc_orinocodev(sizeof(*card), &link->dev, + priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link), spectrum_cs_hard_reset, spectrum_cs_stop_firmware); if (!priv) @@ -194,8 +193,10 @@ spectrum_cs_probe(struct pcmcia_device *link) link->priv = priv; /* Interrupt setup */ - 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 = orinoco_interrupt; + link->irq.Instance = priv; /* General socket configuration defaults can go here. In this * client, we assume very little, and rely on the CIS for @@ -306,7 +307,7 @@ spectrum_cs_config(struct pcmcia_device *link) struct orinoco_private *priv = link->priv; struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; - int ret; + int last_fn, last_ret; void __iomem *mem; /* @@ -323,12 +324,13 @@ spectrum_cs_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL); - if (ret) { + last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL); + if (last_ret) { if (!ignore_cis_vcc) printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " "ignore_cis_vcc=1 parameter.\n"); + cs_error(link, RequestIO, last_ret); goto failed; } @@ -337,16 +339,14 @@ spectrum_cs_config(struct pcmcia_device *link) * a handler to the interrupt, unless the 'Handler' member of * the irq structure is initialized. */ - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* We initialize the hermes structure before completing PCMCIA * configuration just in case the interrupt handler gets * called. */ mem = ioport_map(link->io.BasePort1, link->io.NumPorts1); if (!mem) - goto failed; + goto cs_failed; hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); @@ -355,9 +355,8 @@ spectrum_cs_config(struct pcmcia_device *link) * the I/O windows and the interrupt mapping, and putting the * card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, + pcmcia_request_configuration(link, &link->conf)); /* Ok, we have the configuration, prepare to register the netdev */ card->node.major = card->node.minor = 0; @@ -387,6 +386,9 @@ spectrum_cs_config(struct pcmcia_device *link) * net_device has been registered */ return 0; + cs_failed: + cs_error(link, last_fn, last_ret); + failed: spectrum_cs_release(link); return -ENODEV; diff --git a/trunk/drivers/net/wireless/ray_cs.c b/trunk/drivers/net/wireless/ray_cs.c index 5b8e3e4cdd9f..1c88c2ea59aa 100644 --- a/trunk/drivers/net/wireless/ray_cs.c +++ b/trunk/drivers/net/wireless/ray_cs.c @@ -71,7 +71,25 @@ typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ #include "rayctl.h" #include "ray_cs.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 RAYLINK_DEBUG +#define PCMCIA_DEBUG RAYLINK_DEBUG +#endif +#ifdef PCMCIA_DEBUG +static int ray_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); */ +#define DEBUG(n, args...) if (pc_debug > (n)) printk(args); +#else +#define DEBUG(n, args...) +#endif /** Prototypes based on PCMCIA skeleton driver *******************************/ static int ray_config(struct pcmcia_device *link); static void ray_release(struct pcmcia_device *link); @@ -307,7 +325,7 @@ static int ray_probe(struct pcmcia_device *p_dev) ray_dev_t *local; struct net_device *dev; - dev_dbg(&p_dev->dev, "ray_attach()\n"); + DEBUG(1, "ray_attach()\n"); /* Allocate space for private device-specific data */ dev = alloc_etherdev(sizeof(ray_dev_t)); @@ -323,7 +341,8 @@ static int ray_probe(struct pcmcia_device *p_dev) p_dev->io.IOAddrLines = 5; /* Interrupt setup. For PCMCIA, driver takes what's given */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = &ray_interrupt; /* General socket configuration */ @@ -332,12 +351,13 @@ static int ray_probe(struct pcmcia_device *p_dev) p_dev->conf.ConfigIndex = 1; p_dev->priv = dev; + p_dev->irq.Instance = dev; local->finder = p_dev; local->card_status = CARD_INSERTED; local->authentication_state = UNAUTHENTICATED; local->num_multi = 0; - dev_dbg(&p_dev->dev, "ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n", + DEBUG(2, "ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n", p_dev, dev, local, &ray_interrupt); /* Raylink entries in the device structure */ @@ -350,7 +370,7 @@ static int ray_probe(struct pcmcia_device *p_dev) #endif /* WIRELESS_SPY */ - dev_dbg(&p_dev->dev, "ray_cs ray_attach calling ether_setup.)\n"); + DEBUG(2, "ray_cs ray_attach calling ether_setup.)\n"); netif_stop_queue(dev); init_timer(&local->timer); @@ -373,7 +393,7 @@ static void ray_detach(struct pcmcia_device *link) struct net_device *dev; ray_dev_t *local; - dev_dbg(&link->dev, "ray_detach\n"); + DEBUG(1, "ray_detach(0x%p)\n", link); this_device = NULL; dev = link->priv; @@ -388,7 +408,7 @@ static void ray_detach(struct pcmcia_device *link) unregister_netdev(dev); free_netdev(dev); } - dev_dbg(&link->dev, "ray_cs ray_detach ending\n"); + DEBUG(2, "ray_cs ray_detach ending\n"); } /* ray_detach */ /*============================================================================= @@ -396,17 +416,19 @@ static void ray_detach(struct pcmcia_device *link) is received, to configure the PCMCIA socket, and to make the 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) #define MAX_TUPLE_SIZE 128 static int ray_config(struct pcmcia_device *link) { - int ret = 0; + int last_fn = 0, last_ret = 0; int i; win_req_t req; memreq_t mem; struct net_device *dev = (struct net_device *)link->priv; ray_dev_t *local = netdev_priv(dev); - dev_dbg(&link->dev, "ray_config\n"); + DEBUG(1, "ray_config(0x%p)\n", link); /* Determine card type and firmware version */ printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n", @@ -418,17 +440,14 @@ static int ray_config(struct pcmcia_device *link) /* Now allocate an interrupt line. Note that this does not actually assign a handler to the interrupt. */ - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); dev->irq = link->irq.AssignedIRQ; /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, + pcmcia_request_configuration(link, &link->conf)); /*** Set up 32k window for shared memory (transmit and control) ************/ req.Attributes = @@ -436,14 +455,10 @@ static int ray_config(struct pcmcia_device *link) req.Base = 0; req.Size = 0x8000; req.AccessSpeed = ray_mem_speed; - ret = pcmcia_request_window(link, &req, &link->win); - if (ret) - goto failed; + CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win)); mem.CardOffset = 0x0000; mem.Page = 0; - ret = pcmcia_map_mem_page(link, link->win, &mem); - if (ret) - goto failed; + CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem)); local->sram = ioremap(req.Base, req.Size); /*** Set up 16k window for shared memory (receive buffer) ***************/ @@ -452,14 +467,11 @@ static int ray_config(struct pcmcia_device *link) req.Base = 0; req.Size = 0x4000; req.AccessSpeed = ray_mem_speed; - ret = pcmcia_request_window(link, &req, &local->rmem_handle); - if (ret) - goto failed; + CS_CHECK(RequestWindow, + pcmcia_request_window(&link, &req, &local->rmem_handle)); mem.CardOffset = 0x8000; mem.Page = 0; - ret = pcmcia_map_mem_page(link, local->rmem_handle, &mem); - if (ret) - goto failed; + CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem)); local->rmem = ioremap(req.Base, req.Size); /*** Set up window for attribute memory ***********************************/ @@ -468,25 +480,22 @@ static int ray_config(struct pcmcia_device *link) req.Base = 0; req.Size = 0x1000; req.AccessSpeed = ray_mem_speed; - ret = pcmcia_request_window(link, &req, &local->amem_handle); - if (ret) - goto failed; + CS_CHECK(RequestWindow, + pcmcia_request_window(&link, &req, &local->amem_handle)); mem.CardOffset = 0x0000; mem.Page = 0; - ret = pcmcia_map_mem_page(link, local->amem_handle, &mem); - if (ret) - goto failed; + CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem)); local->amem = ioremap(req.Base, req.Size); - dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram); - dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem); - dev_dbg(&link->dev, "ray_config amem=%p\n", local->amem); + DEBUG(3, "ray_config sram=%p\n", local->sram); + DEBUG(3, "ray_config rmem=%p\n", local->rmem); + DEBUG(3, "ray_config amem=%p\n", local->amem); if (ray_init(dev) < 0) { ray_release(link); return -ENODEV; } - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if (i != 0) { printk("ray_config register_netdev() failed\n"); @@ -502,7 +511,9 @@ static int ray_config(struct pcmcia_device *link) return 0; -failed: +cs_failed: + cs_error(link, last_fn, last_ret); + ray_release(link); return -ENODEV; } /* ray_config */ @@ -532,9 +543,9 @@ static int ray_init(struct net_device *dev) struct ccs __iomem *pccs; ray_dev_t *local = netdev_priv(dev); struct pcmcia_device *link = local->finder; - dev_dbg(&link->dev, "ray_init(0x%p)\n", dev); + DEBUG(1, "ray_init(0x%p)\n", dev); if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_init - device not present\n"); + DEBUG(0, "ray_init - device not present\n"); return -1; } @@ -556,13 +567,13 @@ static int ray_init(struct net_device *dev) local->fw_ver = local->startup_res.firmware_version[0]; local->fw_bld = local->startup_res.firmware_version[1]; local->fw_var = local->startup_res.firmware_version[2]; - dev_dbg(&link->dev, "ray_init firmware version %d.%d \n", local->fw_ver, + DEBUG(1, "ray_init firmware version %d.%d \n", local->fw_ver, local->fw_bld); local->tib_length = 0x20; if ((local->fw_ver == 5) && (local->fw_bld >= 30)) local->tib_length = local->startup_res.tib_length; - dev_dbg(&link->dev, "ray_init tib_length = 0x%02x\n", local->tib_length); + DEBUG(2, "ray_init tib_length = 0x%02x\n", local->tib_length); /* Initialize CCS's to buffer free state */ pccs = ccs_base(local); for (i = 0; i < NUMBER_OF_CCS; i++) { @@ -581,7 +592,7 @@ static int ray_init(struct net_device *dev) clear_interrupt(local); /* Clear any interrupt from the card */ local->card_status = CARD_AWAITING_PARAM; - dev_dbg(&link->dev, "ray_init ending\n"); + DEBUG(2, "ray_init ending\n"); return 0; } /* ray_init */ @@ -594,9 +605,9 @@ static int dl_startup_params(struct net_device *dev) struct ccs __iomem *pccs; struct pcmcia_device *link = local->finder; - dev_dbg(&link->dev, "dl_startup_params entered\n"); + DEBUG(1, "dl_startup_params entered\n"); if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs dl_startup_params - device not present\n"); + DEBUG(2, "ray_cs dl_startup_params - device not present\n"); return -1; } @@ -614,7 +625,7 @@ static int dl_startup_params(struct net_device *dev) local->dl_param_ccs = ccsindex; pccs = ccs_base(local) + ccsindex; writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd); - dev_dbg(&link->dev, "dl_startup_params start ccsindex = %d\n", + DEBUG(2, "dl_startup_params start ccsindex = %d\n", local->dl_param_ccs); /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { @@ -630,7 +641,7 @@ static int dl_startup_params(struct net_device *dev) local->timer.data = (long)local; local->timer.function = &verify_dl_startup; add_timer(&local->timer); - dev_dbg(&link->dev, + DEBUG(2, "ray_cs dl_startup_params started timer for verify_dl_startup\n"); return 0; } /* dl_startup_params */ @@ -706,11 +717,11 @@ static void verify_dl_startup(u_long data) struct pcmcia_device *link = local->finder; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs verify_dl_startup - device not present\n"); + DEBUG(2, "ray_cs verify_dl_startup - device not present\n"); return; } -#if 0 - { +#ifdef PCMCIA_DEBUG + if (pc_debug > 2) { int i; printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n", @@ -749,7 +760,7 @@ static void start_net(u_long data) int ccsindex; struct pcmcia_device *link = local->finder; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs start_net - device not present\n"); + DEBUG(2, "ray_cs start_net - device not present\n"); return; } /* Fill in the CCS fields for the ECF */ @@ -760,7 +771,7 @@ static void start_net(u_long data) writeb(0, &pccs->var.start_network.update_param); /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { - dev_dbg(&link->dev, "ray start net failed - card not ready for intr\n"); + DEBUG(1, "ray start net failed - card not ready for intr\n"); writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); return; } @@ -779,7 +790,7 @@ static void join_net(u_long data) struct pcmcia_device *link = local->finder; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs join_net - device not present\n"); + DEBUG(2, "ray_cs join_net - device not present\n"); return; } /* Fill in the CCS fields for the ECF */ @@ -791,7 +802,7 @@ static void join_net(u_long data) writeb(0, &pccs->var.join_network.net_initiated); /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { - dev_dbg(&link->dev, "ray join net failed - card not ready for intr\n"); + DEBUG(1, "ray join net failed - card not ready for intr\n"); writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); return; } @@ -810,7 +821,7 @@ static void ray_release(struct pcmcia_device *link) ray_dev_t *local = netdev_priv(dev); int i; - dev_dbg(&link->dev, "ray_release\n"); + DEBUG(1, "ray_release(0x%p)\n", link); del_timer(&local->timer); @@ -818,15 +829,15 @@ static void ray_release(struct pcmcia_device *link) iounmap(local->rmem); iounmap(local->amem); /* Do bother checking to see if these succeed or not */ - i = pcmcia_release_window(link, local->amem_handle); + i = pcmcia_release_window(local->amem_handle); if (i != 0) - dev_dbg(&link->dev, "ReleaseWindow(local->amem) ret = %x\n", i); - i = pcmcia_release_window(link, local->rmem_handle); + DEBUG(0, "ReleaseWindow(local->amem) ret = %x\n", i); + i = pcmcia_release_window(local->rmem_handle); if (i != 0) - dev_dbg(&link->dev, "ReleaseWindow(local->rmem) ret = %x\n", i); + DEBUG(0, "ReleaseWindow(local->rmem) ret = %x\n", i); pcmcia_disable_device(link); - dev_dbg(&link->dev, "ray_release ending\n"); + DEBUG(2, "ray_release ending\n"); } static int ray_suspend(struct pcmcia_device *link) @@ -860,9 +871,9 @@ static int ray_dev_init(struct net_device *dev) ray_dev_t *local = netdev_priv(dev); struct pcmcia_device *link = local->finder; - dev_dbg(&link->dev, "ray_dev_init(dev=%p)\n", dev); + DEBUG(1, "ray_dev_init(dev=%p)\n", dev); if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_dev_init - device not present\n"); + DEBUG(2, "ray_dev_init - device not present\n"); return -1; } #ifdef RAY_IMMEDIATE_INIT @@ -876,7 +887,7 @@ static int ray_dev_init(struct net_device *dev) /* Postpone the card init so that we can still configure the card, * for example using the Wireless Extensions. The init will happen * in ray_open() - Jean II */ - dev_dbg(&link->dev, + DEBUG(1, "ray_dev_init: postponing card init to ray_open() ; Status = %d\n", local->card_status); #endif /* RAY_IMMEDIATE_INIT */ @@ -885,7 +896,7 @@ static int ray_dev_init(struct net_device *dev) memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN); memset(dev->broadcast, 0xff, ETH_ALEN); - dev_dbg(&link->dev, "ray_dev_init ending\n"); + DEBUG(2, "ray_dev_init ending\n"); return 0; } @@ -895,9 +906,9 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map) ray_dev_t *local = netdev_priv(dev); struct pcmcia_device *link = local->finder; /* Dummy routine to satisfy device structure */ - dev_dbg(&link->dev, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map); + DEBUG(1, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map); if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_dev_config - device not present\n"); + DEBUG(2, "ray_dev_config - device not present\n"); return -1; } @@ -913,14 +924,14 @@ static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb, short length = skb->len; if (!pcmcia_dev_present(link)) { - dev_dbg(&link->dev, "ray_dev_start_xmit - device not present\n"); + DEBUG(2, "ray_dev_start_xmit - device not present\n"); dev_kfree_skb(skb); return NETDEV_TX_OK; } - dev_dbg(&link->dev, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev); + DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev); if (local->authentication_state == NEED_TO_AUTH) { - dev_dbg(&link->dev, "ray_cs Sending authentication request.\n"); + DEBUG(0, "ray_cs Sending authentication request.\n"); if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) { local->authentication_state = AUTHENTICATED; netif_stop_queue(dev); @@ -960,7 +971,7 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */ short int addr; /* Address of xmit buffer in card space */ - pr_debug("ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev); + DEBUG(3, "ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev); if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) { printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n", len); @@ -968,9 +979,9 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, } switch (ccsindex = get_free_tx_ccs(local)) { case ECCSBUSY: - pr_debug("ray_hw_xmit tx_ccs table busy\n"); + DEBUG(2, "ray_hw_xmit tx_ccs table busy\n"); case ECCSFULL: - pr_debug("ray_hw_xmit No free tx ccs\n"); + DEBUG(2, "ray_hw_xmit No free tx ccs\n"); case ECARDGONE: netif_stop_queue(dev); return XMIT_NO_CCS; @@ -1007,12 +1018,12 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode); writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate); writeb(0, &pccs->var.tx_request.antenna); - pr_debug("ray_hw_xmit default_tx_rate = 0x%x\n", + DEBUG(3, "ray_hw_xmit default_tx_rate = 0x%x\n", local->net_default_tx_rate); /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { - pr_debug("ray_hw_xmit failed - ECF not ready for intr\n"); + DEBUG(2, "ray_hw_xmit failed - ECF not ready for intr\n"); /* TBD very inefficient to copy packet to buffer, and then not send it, but the alternative is to queue the messages and that won't be done for a while. Maybe set tbusy until a CCS is free? @@ -1029,7 +1040,7 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, { __be16 proto = ((struct ethhdr *)data)->h_proto; if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */ - pr_debug("ray_cs translate_frame DIX II\n"); + DEBUG(3, "ray_cs translate_frame DIX II\n"); /* Copy LLC header to card buffer */ memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc)); memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc), @@ -1045,9 +1056,9 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, len - ETH_HLEN); return (int)sizeof(struct snaphdr_t) - ETH_HLEN; } else { /* already 802 type, and proto is length */ - pr_debug("ray_cs translate_frame 802\n"); + DEBUG(3, "ray_cs translate_frame 802\n"); if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */ - pr_debug("ray_cs translate_frame evil IPX\n"); + DEBUG(3, "ray_cs translate_frame evil IPX\n"); memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN); return 0 - ETH_HLEN; } @@ -1592,7 +1603,7 @@ static int ray_open(struct net_device *dev) struct pcmcia_device *link; link = local->finder; - dev_dbg(&link->dev, "ray_open('%s')\n", dev->name); + DEBUG(1, "ray_open('%s')\n", dev->name); if (link->open == 0) local->num_multi = 0; @@ -1602,7 +1613,7 @@ static int ray_open(struct net_device *dev) if (local->card_status == CARD_AWAITING_PARAM) { int i; - dev_dbg(&link->dev, "ray_open: doing init now !\n"); + DEBUG(1, "ray_open: doing init now !\n"); /* Download startup parameters */ if ((i = dl_startup_params(dev)) < 0) { @@ -1618,7 +1629,7 @@ static int ray_open(struct net_device *dev) else netif_start_queue(dev); - dev_dbg(&link->dev, "ray_open ending\n"); + DEBUG(2, "ray_open ending\n"); return 0; } /* end ray_open */ @@ -1629,7 +1640,7 @@ static int ray_dev_close(struct net_device *dev) struct pcmcia_device *link; link = local->finder; - dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name); + DEBUG(1, "ray_dev_close('%s')\n", dev->name); link->open--; netif_stop_queue(dev); @@ -1645,7 +1656,7 @@ static int ray_dev_close(struct net_device *dev) /*===========================================================================*/ static void ray_reset(struct net_device *dev) { - pr_debug("ray_reset entered\n"); + DEBUG(1, "ray_reset entered\n"); return; } @@ -1658,17 +1669,17 @@ static int interrupt_ecf(ray_dev_t *local, int ccs) struct pcmcia_device *link = local->finder; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n"); + DEBUG(2, "ray_cs interrupt_ecf - device not present\n"); return -1; } - dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs); + DEBUG(2, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs); while (i && (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET)) i--; if (i == 0) { - dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n"); + DEBUG(2, "ray_cs interrupt_ecf card not ready for interrupt\n"); return -1; } /* Fill the mailbox, then kick the card */ @@ -1687,12 +1698,12 @@ static int get_free_tx_ccs(ray_dev_t *local) struct pcmcia_device *link = local->finder; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n"); + DEBUG(2, "ray_cs get_free_tx_ccs - device not present\n"); return ECARDGONE; } if (test_and_set_bit(0, &local->tx_ccs_lock)) { - dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n"); + DEBUG(1, "ray_cs tx_ccs_lock busy\n"); return ECCSBUSY; } @@ -1705,7 +1716,7 @@ static int get_free_tx_ccs(ray_dev_t *local) } } local->tx_ccs_lock = 0; - dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n"); + DEBUG(2, "ray_cs ERROR no free tx CCS for raylink card\n"); return ECCSFULL; } /* get_free_tx_ccs */ @@ -1719,11 +1730,11 @@ static int get_free_ccs(ray_dev_t *local) struct pcmcia_device *link = local->finder; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n"); + DEBUG(2, "ray_cs get_free_ccs - device not present\n"); return ECARDGONE; } if (test_and_set_bit(0, &local->ccs_lock)) { - dev_dbg(&link->dev, "ray_cs ccs_lock busy\n"); + DEBUG(1, "ray_cs ccs_lock busy\n"); return ECCSBUSY; } @@ -1736,7 +1747,7 @@ static int get_free_ccs(ray_dev_t *local) } } local->ccs_lock = 0; - dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n"); + DEBUG(1, "ray_cs ERROR no free CCS for raylink card\n"); return ECCSFULL; } /* get_free_ccs */ @@ -1812,7 +1823,7 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev) struct pcmcia_device *link = local->finder; struct status __iomem *p = local->sram + STATUS_BASE; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n"); + DEBUG(2, "ray_cs net_device_stats - device not present\n"); return &local->stats; } if (readb(&p->mrx_overflow_for_host)) { @@ -1845,12 +1856,12 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, struct ccs __iomem *pccs; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_update_parm - device not present\n"); + DEBUG(2, "ray_update_parm - device not present\n"); return; } if ((ccsindex = get_free_ccs(local)) < 0) { - dev_dbg(&link->dev, "ray_update_parm - No free ccs\n"); + DEBUG(0, "ray_update_parm - No free ccs\n"); return; } pccs = ccs_base(local) + ccsindex; @@ -1863,7 +1874,7 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, } /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { - dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n"); + DEBUG(0, "ray_cs associate failed - ECF not ready for intr\n"); writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); } } @@ -1880,12 +1891,12 @@ static void ray_update_multi_list(struct net_device *dev, int all) void __iomem *p = local->sram + HOST_TO_ECF_BASE; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_update_multi_list - device not present\n"); + DEBUG(2, "ray_update_multi_list - device not present\n"); return; } else - dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev); + DEBUG(2, "ray_update_multi_list(%p)\n", dev); if ((ccsindex = get_free_ccs(local)) < 0) { - dev_dbg(&link->dev, "ray_update_multi - No free ccs\n"); + DEBUG(1, "ray_update_multi - No free ccs\n"); return; } pccs = ccs_base(local) + ccsindex; @@ -1899,7 +1910,7 @@ static void ray_update_multi_list(struct net_device *dev, int all) for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) { memcpy_toio(p, dmi->dmi_addr, ETH_ALEN); - dev_dbg(&link->dev, + DEBUG(1, "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n", dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], dmi->dmi_addr[3], @@ -1910,12 +1921,12 @@ static void ray_update_multi_list(struct net_device *dev, int all) if (i > 256 / ADDRLEN) i = 256 / ADDRLEN; writeb((UCHAR) i, &pccs->var); - dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i); + DEBUG(1, "ray_cs update_multi %d addresses in list\n", i); /* Interrupt the firmware to process the command */ local->num_multi = i; } if (interrupt_ecf(local, ccsindex)) { - dev_dbg(&link->dev, + DEBUG(1, "ray_cs update_multi failed - ECF not ready for intr\n"); writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); } @@ -1927,11 +1938,11 @@ static void set_multicast_list(struct net_device *dev) ray_dev_t *local = netdev_priv(dev); UCHAR promisc; - pr_debug("ray_cs set_multicast_list(%p)\n", dev); + DEBUG(2, "ray_cs set_multicast_list(%p)\n", dev); if (dev->flags & IFF_PROMISC) { if (local->sparm.b5.a_promiscuous_mode == 0) { - pr_debug("ray_cs set_multicast_list promisc on\n"); + DEBUG(1, "ray_cs set_multicast_list promisc on\n"); local->sparm.b5.a_promiscuous_mode = 1; promisc = 1; ray_update_parm(dev, OBJID_promiscuous_mode, @@ -1939,7 +1950,7 @@ static void set_multicast_list(struct net_device *dev) } } else { if (local->sparm.b5.a_promiscuous_mode == 1) { - pr_debug("ray_cs set_multicast_list promisc off\n"); + DEBUG(1, "ray_cs set_multicast_list promisc off\n"); local->sparm.b5.a_promiscuous_mode = 0; promisc = 0; ray_update_parm(dev, OBJID_promiscuous_mode, @@ -1973,19 +1984,19 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */ return IRQ_NONE; - pr_debug("ray_cs: interrupt for *dev=%p\n", dev); + DEBUG(4, "ray_cs: interrupt for *dev=%p\n", dev); local = netdev_priv(dev); link = (struct pcmcia_device *)local->finder; if (!pcmcia_dev_present(link)) { - pr_debug( - "ray_cs interrupt from device not present or suspended.\n"); + DEBUG(2, + "ray_cs interrupt from device not present or suspended.\n"); return IRQ_NONE; } rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index); if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) { - dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex); + DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex); clear_interrupt(local); return IRQ_HANDLED; } @@ -1997,33 +2008,33 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */ del_timer(&local->timer); if (status == CCS_COMMAND_COMPLETE) { - dev_dbg(&link->dev, + DEBUG(1, "ray_cs interrupt download_startup_parameters OK\n"); } else { - dev_dbg(&link->dev, + DEBUG(1, "ray_cs interrupt download_startup_parameters fail\n"); } break; case CCS_UPDATE_PARAMS: - dev_dbg(&link->dev, "ray_cs interrupt update params done\n"); + DEBUG(1, "ray_cs interrupt update params done\n"); if (status != CCS_COMMAND_COMPLETE) { tmp = readb(&pccs->var.update_param. failure_cause); - dev_dbg(&link->dev, + DEBUG(0, "ray_cs interrupt update params failed - reason %d\n", tmp); } break; case CCS_REPORT_PARAMS: - dev_dbg(&link->dev, "ray_cs interrupt report params done\n"); + DEBUG(1, "ray_cs interrupt report params done\n"); break; case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */ - dev_dbg(&link->dev, + DEBUG(1, "ray_cs interrupt CCS Update Multicast List done\n"); break; case CCS_UPDATE_POWER_SAVINGS_MODE: - dev_dbg(&link->dev, + DEBUG(1, "ray_cs interrupt update power save mode done\n"); break; case CCS_START_NETWORK: @@ -2032,11 +2043,11 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) if (readb (&pccs->var.start_network.net_initiated) == 1) { - dev_dbg(&link->dev, + DEBUG(0, "ray_cs interrupt network \"%s\" started\n", local->sparm.b4.a_current_ess_id); } else { - dev_dbg(&link->dev, + DEBUG(0, "ray_cs interrupt network \"%s\" joined\n", local->sparm.b4.a_current_ess_id); } @@ -2064,12 +2075,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) local->timer.expires = jiffies + HZ * 5; local->timer.data = (long)local; if (status == CCS_START_NETWORK) { - dev_dbg(&link->dev, + DEBUG(0, "ray_cs interrupt network \"%s\" start failed\n", local->sparm.b4.a_current_ess_id); local->timer.function = &start_net; } else { - dev_dbg(&link->dev, + DEBUG(0, "ray_cs interrupt network \"%s\" join failed\n", local->sparm.b4.a_current_ess_id); local->timer.function = &join_net; @@ -2080,19 +2091,19 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) case CCS_START_ASSOCIATION: if (status == CCS_COMMAND_COMPLETE) { local->card_status = CARD_ASSOC_COMPLETE; - dev_dbg(&link->dev, "ray_cs association successful\n"); + DEBUG(0, "ray_cs association successful\n"); } else { - dev_dbg(&link->dev, "ray_cs association failed,\n"); + DEBUG(0, "ray_cs association failed,\n"); local->card_status = CARD_ASSOC_FAILED; join_net((u_long) local); } break; case CCS_TX_REQUEST: if (status == CCS_COMMAND_COMPLETE) { - dev_dbg(&link->dev, + DEBUG(3, "ray_cs interrupt tx request complete\n"); } else { - dev_dbg(&link->dev, + DEBUG(1, "ray_cs interrupt tx request failed\n"); } if (!sniffer) @@ -2100,21 +2111,21 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) netif_wake_queue(dev); break; case CCS_TEST_MEMORY: - dev_dbg(&link->dev, "ray_cs interrupt mem test done\n"); + DEBUG(1, "ray_cs interrupt mem test done\n"); break; case CCS_SHUTDOWN: - dev_dbg(&link->dev, + DEBUG(1, "ray_cs interrupt Unexpected CCS returned - Shutdown\n"); break; case CCS_DUMP_MEMORY: - dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n"); + DEBUG(1, "ray_cs interrupt dump memory done\n"); break; case CCS_START_TIMER: - dev_dbg(&link->dev, + DEBUG(2, "ray_cs interrupt DING - raylink timer expired\n"); break; default: - dev_dbg(&link->dev, + DEBUG(1, "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n", rcsindex, cmd); } @@ -2128,7 +2139,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) ray_rx(dev, local, prcs); break; case REJOIN_NET_COMPLETE: - dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n"); + DEBUG(1, "ray_cs interrupt rejoin net complete\n"); local->card_status = CARD_ACQ_COMPLETE; /* do we need to clear tx buffers CCS's? */ if (local->sparm.b4.a_network_type == ADHOC) { @@ -2138,7 +2149,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete. bssid, ADDRLEN); - dev_dbg(&link->dev, + DEBUG(1, "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n", local->bss_id[0], local->bss_id[1], local->bss_id[2], local->bss_id[3], @@ -2148,15 +2159,15 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) } break; case ROAMING_INITIATED: - dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n"); + DEBUG(1, "ray_cs interrupt roaming initiated\n"); netif_stop_queue(dev); local->card_status = CARD_DOING_ACQ; break; case JAPAN_CALL_SIGN_RXD: - dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n"); + DEBUG(1, "ray_cs interrupt japan call sign rx\n"); break; default: - dev_dbg(&link->dev, + DEBUG(1, "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n", rcsindex, (unsigned int)readb(&prcs->interrupt_id)); @@ -2175,7 +2186,7 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local, int rx_len; unsigned int pkt_addr; void __iomem *pmsg; - pr_debug("ray_rx process rx packet\n"); + DEBUG(4, "ray_rx process rx packet\n"); /* Calculate address of packet within Rx buffer */ pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8) @@ -2188,28 +2199,28 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local, pmsg = local->rmem + pkt_addr; switch (readb(pmsg)) { case DATA_TYPE: - pr_debug("ray_rx data type\n"); + DEBUG(4, "ray_rx data type\n"); rx_data(dev, prcs, pkt_addr, rx_len); break; case AUTHENTIC_TYPE: - pr_debug("ray_rx authentic type\n"); + DEBUG(4, "ray_rx authentic type\n"); if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); else rx_authenticate(local, prcs, pkt_addr, rx_len); break; case DEAUTHENTIC_TYPE: - pr_debug("ray_rx deauth type\n"); + DEBUG(4, "ray_rx deauth type\n"); if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); else rx_deauthenticate(local, prcs, pkt_addr, rx_len); break; case NULL_MSG_TYPE: - pr_debug("ray_cs rx NULL msg\n"); + DEBUG(3, "ray_cs rx NULL msg\n"); break; case BEACON_TYPE: - pr_debug("ray_rx beacon type\n"); + DEBUG(4, "ray_rx beacon type\n"); if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); @@ -2222,7 +2233,7 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local, ray_get_stats(dev); break; default: - pr_debug("ray_cs unknown pkt type %2x\n", + DEBUG(0, "ray_cs unknown pkt type %2x\n", (unsigned int)readb(pmsg)); break; } @@ -2251,7 +2262,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN)) { - pr_debug( + DEBUG(0, "ray_cs invalid packet length %d received \n", rx_len); return; @@ -2262,17 +2273,17 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN)) { - pr_debug( + DEBUG(0, "ray_cs invalid packet length %d received \n", rx_len); return; } } } - pr_debug("ray_cs rx_data packet\n"); + DEBUG(4, "ray_cs rx_data packet\n"); /* If fragmented packet, verify sizes of fragments add up */ if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) { - pr_debug("ray_cs rx'ed fragment\n"); + DEBUG(1, "ray_cs rx'ed fragment\n"); tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8) + readb(&prcs->var.rx_packet.totalpacketlength[1]); total_len = tmp; @@ -2290,7 +2301,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, } while (1); if (tmp < 0) { - pr_debug( + DEBUG(0, "ray_cs rx_data fragment lengths don't add up\n"); local->stats.rx_dropped++; release_frag_chain(local, prcs); @@ -2302,7 +2313,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, skb = dev_alloc_skb(total_len + 5); if (skb == NULL) { - pr_debug("ray_cs rx_data could not allocate skb\n"); + DEBUG(0, "ray_cs rx_data could not allocate skb\n"); local->stats.rx_dropped++; if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) release_frag_chain(local, prcs); @@ -2310,7 +2321,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, } skb_reserve(skb, 2); /* Align IP on 16 byte (TBD check this) */ - pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len, + DEBUG(4, "ray_cs rx_data total_len = %x, rx_len = %x\n", total_len, rx_len); /************************/ @@ -2343,7 +2354,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, tmp = 17; if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) { prcslink = prcs; - pr_debug("ray_cs rx_data in fragment loop\n"); + DEBUG(1, "ray_cs rx_data in fragment loop\n"); do { prcslink = rcs_base(local) + @@ -2415,8 +2426,8 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN); memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN); -#if 0 - if { +#ifdef PCMCIA_DEBUG + if (pc_debug > 3) { print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ", DUMP_PREFIX_NONE, 16, 1, skb->data, 64, true); @@ -2430,7 +2441,7 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) { /* not a snap type so leave it alone */ - pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n", + DEBUG(3, "ray_cs untranslate NOT SNAP %02x %02x %02x\n", psnap->dsap, psnap->ssap, psnap->ctrl); delta = RX_MAC_HEADER_LENGTH - ETH_HLEN; @@ -2439,7 +2450,7 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) } else { /* Its a SNAP */ if (memcmp(psnap->org, org_bridge, 3) == 0) { /* EtherII and nuke the LLC */ - pr_debug("ray_cs untranslate Bridge encap\n"); + DEBUG(3, "ray_cs untranslate Bridge encap\n"); delta = RX_MAC_HEADER_LENGTH + sizeof(struct snaphdr_t) - ETH_HLEN; peth = (struct ethhdr *)(skb->data + delta); @@ -2448,14 +2459,14 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) switch (ntohs(type)) { case ETH_P_IPX: case ETH_P_AARP: - pr_debug("ray_cs untranslate RFC IPX/AARP\n"); + DEBUG(3, "ray_cs untranslate RFC IPX/AARP\n"); delta = RX_MAC_HEADER_LENGTH - ETH_HLEN; peth = (struct ethhdr *)(skb->data + delta); peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH); break; default: - pr_debug("ray_cs untranslate RFC default\n"); + DEBUG(3, "ray_cs untranslate RFC default\n"); delta = RX_MAC_HEADER_LENGTH + sizeof(struct snaphdr_t) - ETH_HLEN; peth = (struct ethhdr *)(skb->data + delta); @@ -2471,12 +2482,12 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) } /* TBD reserve skb_reserve(skb, delta); */ skb_pull(skb, delta); - pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta, + DEBUG(3, "untranslate after skb_pull(%d), skb->data = %p\n", delta, skb->data); memcpy(peth->h_dest, destaddr, ADDRLEN); memcpy(peth->h_source, srcaddr, ADDRLEN); -#if 0 - { +#ifdef PCMCIA_DEBUG + if (pc_debug > 3) { int i; printk(KERN_DEBUG "skb->data after untranslate:"); for (i = 0; i < 64; i++) @@ -2518,7 +2529,7 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs) while (tmp--) { writeb(CCS_BUFFER_FREE, &prcslink->buffer_status); if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) { - pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n", + DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex); break; } @@ -2532,9 +2543,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs) static void authenticate(ray_dev_t *local) { struct pcmcia_device *link = local->finder; - dev_dbg(&link->dev, "ray_cs Starting authentication.\n"); + DEBUG(0, "ray_cs Starting authentication.\n"); if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs authenticate - device not present\n"); + DEBUG(2, "ray_cs authenticate - device not present\n"); return; } @@ -2562,11 +2573,11 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs, copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff); /* if we are trying to get authenticated */ if (local->sparm.b4.a_network_type == ADHOC) { - pr_debug("ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", + DEBUG(1, "ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0], msg->var[1], msg->var[2], msg->var[3], msg->var[4], msg->var[5]); if (msg->var[2] == 1) { - pr_debug("ray_cs Sending authentication response.\n"); + DEBUG(0, "ray_cs Sending authentication response.\n"); if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) { local->authentication_state = NEED_TO_AUTH; @@ -2580,13 +2591,13 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs, /* Verify authentication sequence #2 and success */ if (msg->var[2] == 2) { if ((msg->var[3] | msg->var[4]) == 0) { - pr_debug("Authentication successful\n"); + DEBUG(1, "Authentication successful\n"); local->card_status = CARD_AUTH_COMPLETE; associate(local); local->authentication_state = AUTHENTICATED; } else { - pr_debug("Authentication refused\n"); + DEBUG(0, "Authentication refused\n"); local->card_status = CARD_AUTH_REFUSED; join_net((u_long) local); local->authentication_state = @@ -2606,22 +2617,22 @@ static void associate(ray_dev_t *local) struct net_device *dev = link->priv; int ccsindex; if (!(pcmcia_dev_present(link))) { - dev_dbg(&link->dev, "ray_cs associate - device not present\n"); + DEBUG(2, "ray_cs associate - device not present\n"); return; } /* If no tx buffers available, return */ if ((ccsindex = get_free_ccs(local)) < 0) { /* TBD should never be here but... what if we are? */ - dev_dbg(&link->dev, "ray_cs associate - No free ccs\n"); + DEBUG(1, "ray_cs associate - No free ccs\n"); return; } - dev_dbg(&link->dev, "ray_cs Starting association with access point\n"); + DEBUG(1, "ray_cs Starting association with access point\n"); pccs = ccs_base(local) + ccsindex; /* fill in the CCS */ writeb(CCS_START_ASSOCIATION, &pccs->cmd); /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { - dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n"); + DEBUG(1, "ray_cs associate failed - ECF not ready for intr\n"); writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); del_timer(&local->timer); @@ -2644,7 +2655,7 @@ static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, /* UCHAR buff[256]; struct rx_msg *msg = (struct rx_msg *)buff; */ - pr_debug("Deauthentication frame received\n"); + DEBUG(0, "Deauthentication frame received\n"); local->authentication_state = UNAUTHENTICATED; /* Need to reauthenticate or rejoin depending on reason code */ /* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff); @@ -2812,7 +2823,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) /* If no tx buffers available, return */ if ((ccsindex = get_free_tx_ccs(local)) < 0) { - pr_debug("ray_cs send authenticate - No free tx ccs\n"); + DEBUG(1, "ray_cs send authenticate - No free tx ccs\n"); return -1; } @@ -2844,7 +2855,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { - pr_debug( + DEBUG(1, "ray_cs send authentication request failed - ECF not ready for intr\n"); writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); return -1; @@ -2931,9 +2942,9 @@ static int __init init_ray_cs(void) { int rc; - pr_debug("%s\n", rcsid); + DEBUG(1, "%s\n", rcsid); rc = pcmcia_register_driver(&ray_driver); - pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n", + DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n", rc); #ifdef CONFIG_PROC_FS @@ -2953,7 +2964,7 @@ static int __init init_ray_cs(void) static void __exit exit_ray_cs(void) { - pr_debug("ray_cs: cleanup_module\n"); + DEBUG(0, "ray_cs: cleanup_module\n"); #ifdef CONFIG_PROC_FS remove_proc_entry("driver/ray_cs/ray_cs", NULL); diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index 33918fd5b231..431a20ec6db6 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -3656,7 +3656,10 @@ wv_pcmcia_reset(struct net_device * dev) i = pcmcia_access_configuration_register(link, ®); if (i != 0) + { + cs_error(link, AccessConfigurationRegister, i); return FALSE; + } #ifdef DEBUG_CONFIG_INFO printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n", @@ -3667,13 +3670,19 @@ wv_pcmcia_reset(struct net_device * dev) reg.Value = reg.Value | COR_SW_RESET; i = pcmcia_access_configuration_register(link, ®); if (i != 0) + { + cs_error(link, AccessConfigurationRegister, i); return FALSE; + } reg.Action = CS_WRITE; reg.Value = COR_LEVEL_IRQ | COR_CONFIG; i = pcmcia_access_configuration_register(link, ®); if (i != 0) + { + cs_error(link, AccessConfigurationRegister, i); return FALSE; + } #ifdef DEBUG_CONFIG_TRACE printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name); @@ -3848,7 +3857,10 @@ wv_pcmcia_config(struct pcmcia_device * link) { i = pcmcia_request_io(link, &link->io); if (i != 0) + { + cs_error(link, RequestIO, i); break; + } /* * Now allocate an interrupt line. Note that this does not @@ -3856,7 +3868,10 @@ wv_pcmcia_config(struct pcmcia_device * link) */ i = pcmcia_request_irq(link, &link->irq); if (i != 0) + { + cs_error(link, RequestIRQ, i); break; + } /* * This actually configures the PCMCIA socket -- setting up @@ -3865,7 +3880,10 @@ wv_pcmcia_config(struct pcmcia_device * link) link->conf.ConfigIndex = 1; i = pcmcia_request_configuration(link, &link->conf); if (i != 0) + { + cs_error(link, RequestConfiguration, i); break; + } /* * Allocate a small memory window. Note that the struct pcmcia_device @@ -3876,18 +3894,24 @@ wv_pcmcia_config(struct pcmcia_device * link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = mem_speed; - i = pcmcia_request_window(link, &req, &link->win); + i = pcmcia_request_window(&link, &req, &link->win); if (i != 0) + { + cs_error(link, RequestWindow, i); break; + } lp->mem = ioremap(req.Base, req.Size); dev->mem_start = (u_long)lp->mem; dev->mem_end = dev->mem_start + req.Size; mem.CardOffset = 0; mem.Page = 0; - i = pcmcia_map_mem_page(link, link->win, &mem); + i = pcmcia_map_mem_page(link->win, &mem); if (i != 0) + { + cs_error(link, MapMemPage, i); break; + } /* Feed device with this info... */ dev->irq = link->irq.AssignedIRQ; @@ -3899,7 +3923,7 @@ wv_pcmcia_config(struct pcmcia_device * link) lp->mem, dev->irq, (u_int) dev->base_addr); #endif - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if(i != 0) { @@ -4438,7 +4462,8 @@ wavelan_probe(struct pcmcia_device *p_dev) p_dev->io.IOAddrLines = 3; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = wavelan_interrupt; /* General socket configuration */ @@ -4450,7 +4475,7 @@ wavelan_probe(struct pcmcia_device *p_dev) if (!dev) return -ENOMEM; - p_dev->priv = dev; + p_dev->priv = p_dev->irq.Instance = dev; lp = netdev_priv(dev); diff --git a/trunk/drivers/net/wireless/wl3501_cs.c b/trunk/drivers/net/wireless/wl3501_cs.c index 5f0401a52cff..4f1e0cfe609b 100644 --- a/trunk/drivers/net/wireless/wl3501_cs.c +++ b/trunk/drivers/net/wireless/wl3501_cs.c @@ -67,7 +67,23 @@ /* For rough constant delay */ #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_p(a, b) { outb_p(a, b); slow_down_io(); } @@ -668,10 +684,10 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr) int matchflag = 0; struct wl3501_scan_confirm sig; - pr_debug("entry"); + dprintk(3, "entry"); wl3501_get_from_wla(this, addr, &sig, sizeof(sig)); if (sig.status == WL3501_STATUS_SUCCESS) { - pr_debug("success"); + dprintk(3, "success"); if ((this->net_type == IW_MODE_INFRA && (sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) || (this->net_type == IW_MODE_ADHOC && @@ -706,7 +722,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr) } } } else if (sig.status == WL3501_STATUS_TIMEOUT) { - pr_debug("timeout"); + dprintk(3, "timeout"); this->join_sta_bss = 0; for (i = this->join_sta_bss; i < this->bss_cnt; i++) if (!wl3501_mgmt_join(this, i)) @@ -863,7 +879,7 @@ static int wl3501_mgmt_auth(struct wl3501_card *this) .timeout = 1000, }; - pr_debug("entry"); + dprintk(3, "entry"); memcpy(sig.mac_addr, this->bssid, ETH_ALEN); return wl3501_esbq_exec(this, &sig, sizeof(sig)); } @@ -877,7 +893,7 @@ static int wl3501_mgmt_association(struct wl3501_card *this) .cap_info = this->cap_info, }; - pr_debug("entry"); + dprintk(3, "entry"); memcpy(sig.mac_addr, this->bssid, ETH_ALEN); return wl3501_esbq_exec(this, &sig, sizeof(sig)); } @@ -887,7 +903,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr) struct wl3501_card *this = netdev_priv(dev); struct wl3501_join_confirm sig; - pr_debug("entry"); + dprintk(3, "entry"); wl3501_get_from_wla(this, addr, &sig, sizeof(sig)); if (sig.status == WL3501_STATUS_SUCCESS) { if (this->net_type == IW_MODE_INFRA) { @@ -946,7 +962,7 @@ static inline void wl3501_md_confirm_interrupt(struct net_device *dev, { struct wl3501_md_confirm sig; - pr_debug("entry"); + dprintk(3, "entry"); wl3501_get_from_wla(this, addr, &sig, sizeof(sig)); wl3501_free_tx_buffer(this, sig.data); if (netif_queue_stopped(dev)) @@ -1001,7 +1017,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev, static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this, u16 addr, void *sig, int size) { - pr_debug("entry"); + dprintk(3, "entry"); wl3501_get_from_wla(this, addr, &this->sig_get_confirm, sizeof(this->sig_get_confirm)); wake_up(&this->wait); @@ -1013,7 +1029,7 @@ static inline void wl3501_start_confirm_interrupt(struct net_device *dev, { struct wl3501_start_confirm sig; - pr_debug("entry"); + dprintk(3, "entry"); wl3501_get_from_wla(this, addr, &sig, sizeof(sig)); if (sig.status == WL3501_STATUS_SUCCESS) netif_wake_queue(dev); @@ -1025,7 +1041,7 @@ static inline void wl3501_assoc_confirm_interrupt(struct net_device *dev, struct wl3501_card *this = netdev_priv(dev); struct wl3501_assoc_confirm sig; - pr_debug("entry"); + dprintk(3, "entry"); wl3501_get_from_wla(this, addr, &sig, sizeof(sig)); if (sig.status == WL3501_STATUS_SUCCESS) @@ -1037,7 +1053,7 @@ static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this, { struct wl3501_auth_confirm sig; - pr_debug("entry"); + dprintk(3, "entry"); wl3501_get_from_wla(this, addr, &sig, sizeof(sig)); if (sig.status == WL3501_STATUS_SUCCESS) @@ -1053,7 +1069,7 @@ static inline void wl3501_rx_interrupt(struct net_device *dev) u8 sig_id; struct wl3501_card *this = netdev_priv(dev); - pr_debug("entry"); + dprintk(3, "entry"); loop: morepkts = 0; if (!wl3501_esbq_confirm(this)) @@ -1286,7 +1302,7 @@ static int wl3501_reset(struct net_device *dev) wl3501_ack_interrupt(this); wl3501_unblock_interrupt(this); wl3501_mgmt_scan(this, 100); - pr_debug("%s: device reset", dev->name); + dprintk(1, "%s: device reset", dev->name); rc = 0; out: return rc; @@ -1360,7 +1376,7 @@ static int wl3501_open(struct net_device *dev) link->open++; /* Initial WL3501 firmware */ - pr_debug("%s: Initialize WL3501 firmware...", dev->name); + dprintk(1, "%s: Initialize WL3501 firmware...", dev->name); if (wl3501_init_firmware(this)) goto fail; /* Initial device variables */ @@ -1372,7 +1388,7 @@ static int wl3501_open(struct net_device *dev) wl3501_unblock_interrupt(this); wl3501_mgmt_scan(this, 100); rc = 0; - pr_debug("%s: WL3501 opened", dev->name); + dprintk(1, "%s: WL3501 opened", dev->name); printk(KERN_INFO "%s: Card Name: %s\n" "%s: Firmware Date: %s\n", dev->name, this->card_name, @@ -1898,7 +1914,8 @@ static int wl3501_probe(struct pcmcia_device *p_dev) p_dev->io.IOAddrLines = 5; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; + p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = wl3501_interrupt; /* General socket configuration */ @@ -1921,13 +1938,16 @@ static int wl3501_probe(struct pcmcia_device *p_dev) dev->wireless_handlers = &wl3501_handler_def; SET_ETHTOOL_OPS(dev, &ops); netif_stop_queue(dev); - p_dev->priv = dev; + p_dev->priv = p_dev->irq.Instance = dev; return wl3501_config(p_dev); out_link: 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 * @link - FILL_IN @@ -1939,7 +1959,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev) static int wl3501_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; - int i = 0, j, ret; + int i = 0, j, last_fn, last_ret; struct wl3501_card *this; /* Try allocating IO ports. This tries a few fixed addresses. If you @@ -1955,26 +1975,24 @@ static int wl3501_config(struct pcmcia_device *link) if (i == 0) break; } - if (i != 0) + if (i != 0) { + cs_error(link, RequestIO, i); goto failed; + } /* Now allocate an interrupt line. Note that this does not actually * assign a handler to the interrupt. */ - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); /* This actually configures the PCMCIA socket -- setting up the I/O * windows and the interrupt mapping. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &link->dev); + SET_NETDEV_DEV(dev, &handle_to_dev(link)); if (register_netdev(dev)) { printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n"); goto failed; @@ -2023,6 +2041,8 @@ static int wl3501_config(struct pcmcia_device *link) netif_start_queue(dev); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: wl3501_release(link); return -ENODEV; diff --git a/trunk/drivers/parport/parport_cs.c b/trunk/drivers/parport/parport_cs.c index 7dd370fa3439..8fdfa4f537a6 100644 --- a/trunk/drivers/parport/parport_cs.c +++ b/trunk/drivers/parport/parport_cs.c @@ -67,6 +67,14 @@ MODULE_LICENSE("Dual MPL/GPL"); 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 /*====================================================================*/ @@ -95,7 +103,7 @@ static int parport_probe(struct pcmcia_device *link) { parport_info_t *info; - dev_dbg(&link->dev, "parport_attach()\n"); + DEBUG(0, "parport_attach()\n"); /* Create new parport device */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -106,6 +114,7 @@ static int parport_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -123,7 +132,7 @@ static int parport_probe(struct pcmcia_device *link) static void parport_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "parport_detach\n"); + DEBUG(0, "parport_detach(0x%p)\n", link); parport_cs_release(link); @@ -138,6 +147,9 @@ 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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -166,20 +178,18 @@ static int parport_config(struct pcmcia_device *link) { parport_info_t *info = link->priv; struct parport *p; - int ret; + int last_ret, last_fn; - dev_dbg(&link->dev, "parport_config\n"); + DEBUG(0, "parport_config(0x%p)\n", link); - ret = pcmcia_loop_config(link, parport_config_check, NULL); - if (ret) + last_ret = pcmcia_loop_config(link, parport_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_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(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, link->irq.AssignedIRQ, PARPORT_DMA_NONE, @@ -203,6 +213,8 @@ static int parport_config(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: parport_cs_release(link); return -ENODEV; @@ -220,7 +232,7 @@ static void parport_cs_release(struct pcmcia_device *link) { parport_info_t *info = link->priv; - dev_dbg(&link->dev, "parport_release\n"); + DEBUG(0, "parport_release(0x%p)\n", link); if (info->ndev) { struct parport *p = info->port; diff --git a/trunk/drivers/pcmcia/Kconfig b/trunk/drivers/pcmcia/Kconfig index f3ccbccf5f21..17f38a781d47 100644 --- a/trunk/drivers/pcmcia/Kconfig +++ b/trunk/drivers/pcmcia/Kconfig @@ -17,6 +17,24 @@ menuconfig 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 tristate "16-bit PCMCIA support" select CRC32 @@ -178,13 +196,9 @@ config PCMCIA_BCM63XX tristate "bcm63xx pcmcia support" depends on BCM63XX && PCMCIA -config PCMCIA_SOC_COMMON - bool - config PCMCIA_SA1100 tristate "SA1100 support" depends on ARM && ARCH_SA1100 && PCMCIA - select PCMCIA_SOC_COMMON help Say Y here to include support for SA11x0-based PCMCIA or CF sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/ @@ -195,7 +209,6 @@ config PCMCIA_SA1100 config PCMCIA_SA1111 tristate "SA1111 support" depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA - select PCMCIA_SOC_COMMON help Say Y here to include support for SA1111-based PCMCIA or CF sockets, found on the Jornada 720, Graphicsmaster and other @@ -209,28 +222,9 @@ config PCMCIA_PXA2XX depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \ || ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2) - select PCMCIA_SOC_COMMON help 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 bool default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC diff --git a/trunk/drivers/pcmcia/Makefile b/trunk/drivers/pcmcia/Makefile index 382938313991..a03a38acd77d 100644 --- a/trunk/drivers/pcmcia/Makefile +++ b/trunk/drivers/pcmcia/Makefile @@ -22,9 +22,8 @@ obj-$(CONFIG_I82365) += i82365.o obj-$(CONFIG_I82092) += i82092.o obj-$(CONFIG_TCIC) += tcic.o obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o -obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o -obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o -obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o +obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o +obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o obj-$(CONFIG_M32R_PCC) += m32r_pcc.o obj-$(CONFIG_M32R_CFC) += m32r_cfc.o obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o @@ -36,6 +35,9 @@ obj-$(CONFIG_BFIN_CFPCMCIA) += bfin_cf_pcmcia.o obj-$(CONFIG_AT91_CF) += at91_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-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o @@ -75,4 +77,4 @@ pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o -obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y) +obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y) diff --git a/trunk/drivers/pcmcia/cardbus.c b/trunk/drivers/pcmcia/cardbus.c index 4cd70d056810..db77e1f3309a 100644 --- a/trunk/drivers/pcmcia/cardbus.c +++ b/trunk/drivers/pcmcia/cardbus.c @@ -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) { if (s->cb_cis_virt) { - dev_dbg(&s->dev, "cb_release_cis_mem()\n"); + cs_dbg(s, 1, "cb_release_cis_mem()\n"); iounmap(s->cb_cis_virt); s->cb_cis_virt = 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 resource *res; - dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len); + cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len); dev = pci_get_slot(s->cb_dev->subordinate, 0); if (!dev) diff --git a/trunk/drivers/pcmcia/cirrus.h b/trunk/drivers/pcmcia/cirrus.h index 446a4576e73e..ecd4fc7f666f 100644 --- a/trunk/drivers/pcmcia/cirrus.h +++ b/trunk/drivers/pcmcia/cirrus.h @@ -30,6 +30,16 @@ #ifndef _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_FIFO_CTL 0x17 /* FIFO control */ #define PD67_MISC_CTL_2 0x1E /* Misc control 2 */ diff --git a/trunk/drivers/pcmcia/cistpl.c b/trunk/drivers/pcmcia/cistpl.c index 8c1b73cf021b..6c4a4fc83630 100644 --- a/trunk/drivers/pcmcia/cistpl.c +++ b/trunk/drivers/pcmcia/cistpl.c @@ -138,7 +138,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, void __iomem *sys, *end; unsigned char *buf = ptr; - dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); + cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); if (attr & IS_INDIRECT) { /* 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; } } - dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", + cs_dbg(s, 3, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", *(u_char *)(ptr+0), *(u_char *)(ptr+1), *(u_char *)(ptr+2), *(u_char *)(ptr+3)); return 0; @@ -204,7 +204,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, void __iomem *sys, *end; unsigned char *buf = ptr; - dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); + cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); if (attr & IS_INDIRECT) { /* 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; } if (i == MAX_TUPLES) { - dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n"); + cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n"); return -ENOSPC; } @@ -1440,7 +1440,7 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) break; } if (ret) - pr_debug("parse_tuple failed %d\n", ret); + __cs_dbg(0, "parse_tuple failed %d\n", ret); return ret; } EXPORT_SYMBOL(pcmcia_parse_tuple); @@ -1482,67 +1482,6 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t } 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 diff --git a/trunk/drivers/pcmcia/cs.c b/trunk/drivers/pcmcia/cs.c index 790af87a922f..698d75cda084 100644 --- a/trunk/drivers/pcmcia/cs.c +++ b/trunk/drivers/pcmcia/cs.c @@ -61,6 +61,17 @@ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */ /* Access speed for attribute memory windows */ 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 = { .csc_mask = SS_DETECT, @@ -179,7 +190,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops) return -EINVAL; - dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops); + cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops); spin_lock_init(&socket->lock); @@ -251,13 +262,6 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) 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; err: @@ -278,7 +282,7 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket) if (!socket) return; - dev_dbg(&socket->dev, "pcmcia_unregister_socket(0x%p)\n", socket->ops); + cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops); if (socket->thread) kthread_stop(socket->thread); @@ -331,7 +335,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority) if (s->state & SOCKET_CARDBUS) return 0; - dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n", + cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n", event, priority, s->callback); if (!s->callback) @@ -348,7 +352,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority) static void socket_remove_drivers(struct pcmcia_socket *skt) { - dev_dbg(&skt->dev, "remove_drivers\n"); + cs_dbg(skt, 4, "remove_drivers\n"); send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); } @@ -357,7 +361,7 @@ static int socket_reset(struct pcmcia_socket *skt) { int status, i; - dev_dbg(&skt->dev, "reset\n"); + cs_dbg(skt, 4, "reset\n"); skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET; skt->ops->set_socket(skt, &skt->socket); @@ -379,7 +383,7 @@ static int socket_reset(struct pcmcia_socket *skt) msleep(unreset_check * 10); } - dev_printk(KERN_ERR, &skt->dev, "time out after reset.\n"); + cs_err(skt, "time out after reset.\n"); return -ETIMEDOUT; } @@ -393,7 +397,7 @@ static void socket_shutdown(struct pcmcia_socket *s) { int status; - dev_dbg(&s->dev, "shutdown\n"); + cs_dbg(s, 4, "shutdown\n"); socket_remove_drivers(s); s->state &= SOCKET_INUSE | SOCKET_PRESENT; @@ -428,7 +432,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) { int status, i; - dev_dbg(&skt->dev, "setup\n"); + cs_dbg(skt, 4, "setup\n"); skt->ops->get_status(skt, &status); if (!(status & SS_DETECT)) @@ -448,15 +452,13 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) } if (status & SS_PENDING) { - dev_printk(KERN_ERR, &skt->dev, - "voltage interrogation timed out.\n"); + cs_err(skt, "voltage interrogation timed out.\n"); return -ETIMEDOUT; } if (status & SS_CARDBUS) { if (!(skt->features & SS_CAP_CARDBUS)) { - dev_printk(KERN_ERR, &skt->dev, - "cardbus cards are not supported.\n"); + cs_err(skt, "cardbus cards are not supported.\n"); return -EINVAL; } skt->state |= SOCKET_CARDBUS; @@ -470,7 +472,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) else if (!(status & SS_XVCARD)) skt->socket.Vcc = skt->socket.Vpp = 50; else { - dev_printk(KERN_ERR, &skt->dev, "unsupported voltage key.\n"); + cs_err(skt, "unsupported voltage key.\n"); return -EIO; } @@ -487,7 +489,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) skt->ops->get_status(skt, &status); if (!(status & SS_POWERON)) { - dev_printk(KERN_ERR, &skt->dev, "unable to apply power.\n"); + cs_err(skt, "unable to apply power.\n"); return -EIO; } @@ -507,7 +509,7 @@ static int socket_insert(struct pcmcia_socket *skt) { int ret; - dev_dbg(&skt->dev, "insert\n"); + cs_dbg(skt, 4, "insert\n"); if (!cs_socket_get(skt)) return -ENODEV; @@ -527,7 +529,7 @@ static int socket_insert(struct pcmcia_socket *skt) skt->state |= SOCKET_CARDBUS_CONFIG; } #endif - dev_dbg(&skt->dev, "insert done\n"); + cs_dbg(skt, 4, "insert done\n"); send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); } else { @@ -574,7 +576,7 @@ static int socket_late_resume(struct pcmcia_socket *skt) * FIXME: need a better check here for cardbus cards. */ if (verify_cis_cache(skt) != 0) { - dev_dbg(&skt->dev, "cis mismatch - different card\n"); + cs_dbg(skt, 4, "cis mismatch - different card\n"); socket_remove_drivers(skt); destroy_cis_cache(skt); /* @@ -585,7 +587,7 @@ static int socket_late_resume(struct pcmcia_socket *skt) msleep(200); send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); } else { - dev_dbg(&skt->dev, "cis matches cache\n"); + cs_dbg(skt, 4, "cis matches cache\n"); send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW); } } else { @@ -721,7 +723,7 @@ static int pccardd(void *__skt) void pcmcia_parse_events(struct pcmcia_socket *s, u_int events) { unsigned long flags; - dev_dbg(&s->dev, "parse_events: events %08x\n", events); + cs_dbg(s, 4, "parse_events: events %08x\n", events); if (s->thread) { spin_lock_irqsave(&s->thread_lock, flags); s->thread_events |= events; @@ -771,22 +773,19 @@ int pcmcia_reset_card(struct pcmcia_socket *skt) { int ret; - dev_dbg(&skt->dev, "resetting socket\n"); + cs_dbg(skt, 1, "resetting socket\n"); mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { - dev_dbg(&skt->dev, "can't reset, not present\n"); ret = -ENODEV; break; } if (skt->state & SOCKET_SUSPEND) { - dev_dbg(&skt->dev, "can't reset, suspended\n"); ret = -EBUSY; break; } if (skt->state & SOCKET_CARDBUS) { - dev_dbg(&skt->dev, "can't reset, is cardbus\n"); ret = -EPERM; break; } @@ -819,7 +818,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) { int ret; - dev_dbg(&skt->dev, "suspending socket\n"); + cs_dbg(skt, 1, "suspending socket\n"); mutex_lock(&skt->skt_mutex); do { @@ -849,7 +848,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) { int ret; - dev_dbg(&skt->dev, "waking up socket\n"); + cs_dbg(skt, 1, "waking up socket\n"); mutex_lock(&skt->skt_mutex); do { @@ -877,7 +876,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt) { int ret; - dev_dbg(&skt->dev, "user eject request\n"); + cs_dbg(skt, 1, "user eject request\n"); mutex_lock(&skt->skt_mutex); do { @@ -906,7 +905,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) { int ret; - dev_dbg(&skt->dev, "user insert request\n"); + cs_dbg(skt, 1, "user insert request\n"); mutex_lock(&skt->skt_mutex); do { diff --git a/trunk/drivers/pcmcia/cs_internal.h b/trunk/drivers/pcmcia/cs_internal.h index 3bc02d53a3a3..1f4098f1354d 100644 --- a/trunk/drivers/pcmcia/cs_internal.h +++ b/trunk/drivers/pcmcia/cs_internal.h @@ -107,6 +107,28 @@ 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": @@ -148,6 +170,10 @@ extern struct rw_semaphore pcmcia_socket_list_rwsem; extern struct list_head pcmcia_socket_list; 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); struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr); @@ -173,22 +199,6 @@ int pcmcia_replace_cis(struct pcmcia_socket *s, const u8 *data, const size_t len); 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 */ int pcmcia_validate_mem(struct pcmcia_socket *s); struct resource *pcmcia_find_io_region(unsigned long base, diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 05893d41dd41..f5b7079f13d3 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -41,11 +41,129 @@ MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("PCMCIA Driver Services"); 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; /*====================================================================*/ +/* 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) { struct pcmcia_device_id *did = p_drv->id_table; @@ -185,7 +303,7 @@ int pcmcia_register_driver(struct pcmcia_driver *driver) spin_lock_init(&driver->dynids.lock); INIT_LIST_HEAD(&driver->dynids.list); - pr_debug("registering driver %s\n", driver->drv.name); + ds_dbg(3, "registering driver %s\n", driver->drv.name); error = driver_register(&driver->drv); if (error < 0) @@ -205,7 +323,7 @@ EXPORT_SYMBOL(pcmcia_register_driver); */ void pcmcia_unregister_driver(struct pcmcia_driver *driver) { - pr_debug("unregistering driver %s\n", driver->drv.name); + ds_dbg(3, "unregistering driver %s\n", driver->drv.name); driver_unregister(&driver->drv); pcmcia_free_dynids(driver); } @@ -232,14 +350,14 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev) static void pcmcia_release_function(struct kref *ref) { struct config_t *c = container_of(ref, struct config_t, ref); - pr_debug("releasing config_t\n"); + ds_dbg(1, "releasing config_t\n"); kfree(c); } static void pcmcia_release_dev(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - dev_dbg(dev, "releasing device\n"); + ds_dev_dbg(1, dev, "releasing device\n"); pcmcia_put_socket(p_dev->socket); kfree(p_dev->devname); kref_put(&p_dev->function_config->ref, pcmcia_release_function); @@ -249,7 +367,7 @@ static void pcmcia_release_dev(struct device *dev) static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc) { if (!s->pcmcia_state.device_add_pending) { - dev_dbg(&s->dev, "scheduling to add %s secondary" + ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary" " device to %d\n", mfc ? "mfc" : "pfc", s->sock); s->pcmcia_state.device_add_pending = 1; s->pcmcia_state.mfc_pfc = mfc; @@ -287,7 +405,7 @@ static int pcmcia_device_probe(struct device * dev) */ did = dev_get_drvdata(&p_dev->dev); - dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name); + ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name); if ((!p_drv->probe) || (!p_dev->function_config) || (!try_module_get(p_drv->owner))) { @@ -310,7 +428,7 @@ static int pcmcia_device_probe(struct device * dev) ret = p_drv->probe(p_dev); if (ret) { - dev_dbg(dev, "binding to %s failed with %d\n", + ds_dev_dbg(1, dev, "binding to %s failed with %d\n", p_drv->drv.name, ret); goto put_module; } @@ -338,7 +456,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le struct pcmcia_device *tmp; unsigned long flags; - dev_dbg(leftover ? &leftover->dev : &s->dev, + ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev, "pcmcia_card_remove(%d) %s\n", s->sock, leftover ? leftover->devname : ""); @@ -357,7 +475,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le p_dev->_removed=1; spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - dev_dbg(&p_dev->dev, "unregistering device\n"); + ds_dev_dbg(2, &p_dev->dev, "unregistering device\n"); device_unregister(&p_dev->dev); } @@ -374,7 +492,7 @@ static int pcmcia_device_remove(struct device * dev) p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); - dev_dbg(dev, "removing device\n"); + ds_dev_dbg(1, dev, "removing device\n"); /* If we're removing the primary module driving a * pseudo multi-function card, we need to unbind @@ -454,7 +572,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) } if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_DEVICE_GEO, devgeo)) { - dev_dbg(&p_dev->dev, + ds_dev_dbg(0, &p_dev->dev, "mem device geometry probably means " "FUNCID_MEMORY\n"); p_dev->func_id = CISTPL_FUNCID_MEMORY; @@ -510,7 +628,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f mutex_lock(&device_add_lock); - pr_debug("adding device to %d, function %d\n", s->sock, function); + ds_dbg(3, "adding device to %d, function %d\n", s->sock, function); /* max of 4 devices per card */ if (s->device_count == 4) @@ -536,7 +654,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)); if (!p_dev->devname) goto err_free; - dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname); + ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname); spin_lock_irqsave(&pcmcia_dev_list_lock, flags); @@ -559,7 +677,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); if (!p_dev->function_config) { - dev_dbg(&p_dev->dev, "creating config_t\n"); + ds_dev_dbg(3, &p_dev->dev, "creating config_t\n"); p_dev->function_config = kzalloc(sizeof(struct config_t), GFP_KERNEL); if (!p_dev->function_config) @@ -604,20 +722,20 @@ static int pcmcia_card_add(struct pcmcia_socket *s) int ret = 0; if (!(s->resource_setup_done)) { - dev_dbg(&s->dev, + ds_dev_dbg(3, &s->dev, "no resources available, delaying card_add\n"); return -EAGAIN; /* try again, but later... */ } if (pcmcia_validate_mem(s)) { - dev_dbg(&s->dev, "validating mem resources failed, " + ds_dev_dbg(3, &s->dev, "validating mem resources failed, " "delaying card_add\n"); return -EAGAIN; /* try again, but later... */ } ret = pccard_validate_cis(s, &no_chains); if (ret || !no_chains) { - dev_dbg(&s->dev, "invalid CIS or invalid resources\n"); + ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n"); return -ENODEV; } @@ -638,7 +756,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work) { struct pcmcia_socket *s = container_of(work, struct pcmcia_socket, device_add); - dev_dbg(&s->dev, "adding additional device to %d\n", s->sock); + ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock); pcmcia_device_add(s, s->pcmcia_state.mfc_pfc); s->pcmcia_state.device_add_pending = 0; s->pcmcia_state.mfc_pfc = 0; @@ -648,7 +766,7 @@ static int pcmcia_requery(struct device *dev, void * _data) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); if (!p_dev->dev.driver) { - dev_dbg(dev, "update device information\n"); + ds_dev_dbg(1, dev, "update device information\n"); pcmcia_device_query(p_dev); } @@ -662,7 +780,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) unsigned long flags; /* must be called with skt_mutex held */ - dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock); + ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock); spin_lock_irqsave(&pcmcia_dev_list_lock, flags); if (list_empty(&skt->devices_list)) @@ -717,7 +835,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) if (!filename) return -EINVAL; - dev_dbg(&dev->dev, "trying to load CIS file %s\n", filename); + ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename); if (request_firmware(&fw, filename, &dev->dev) == 0) { if (fw->size >= CISTPL_MAX_CIS_SIZE) { @@ -835,14 +953,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, * after it has re-checked that there is no possible module * with a prod_id/manf_id/card_id match. */ - dev_dbg(&dev->dev, + ds_dev_dbg(0, &dev->dev, "skipping FUNC_ID match until userspace interaction\n"); if (!dev->allow_func_id_match) return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { - dev_dbg(&dev->dev, "device needs a fake CIS\n"); + ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n"); if (!dev->socket->fake_cis) pcmcia_load_firmware(dev, did->cisfile); @@ -874,9 +992,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { /* match dynamic devices first */ spin_lock(&p_drv->dynids.lock); list_for_each_entry(dynid, &p_drv->dynids.list, node) { - dev_dbg(dev, "trying to match to %s\n", drv->name); + ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name); if (pcmcia_devmatch(p_dev, &dynid->id)) { - dev_dbg(dev, "matched to %s\n", drv->name); + ds_dev_dbg(0, dev, "matched to %s\n", drv->name); spin_unlock(&p_drv->dynids.lock); return 1; } @@ -886,15 +1004,15 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { #ifdef CONFIG_PCMCIA_IOCTL /* matching by cardmgr */ if (p_dev->cardmgr == p_drv) { - dev_dbg(dev, "cardmgr matched to %s\n", drv->name); + ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name); return 1; } #endif while (did && did->match_flags) { - dev_dbg(dev, "trying to match to %s\n", drv->name); + ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name); if (pcmcia_devmatch(p_dev, did)) { - dev_dbg(dev, "matched to %s\n", drv->name); + ds_dev_dbg(0, dev, "matched to %s\n", drv->name); return 1; } did++; @@ -1100,7 +1218,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) if (p_dev->suspended) return 0; - dev_dbg(dev, "suspending\n"); + ds_dev_dbg(2, dev, "suspending\n"); if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1120,7 +1238,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) } if (p_dev->device_no == p_dev->func) { - dev_dbg(dev, "releasing configuration\n"); + ds_dev_dbg(2, dev, "releasing configuration\n"); pcmcia_release_configuration(p_dev); } @@ -1140,7 +1258,7 @@ static int pcmcia_dev_resume(struct device * dev) if (!p_dev->suspended) return 0; - dev_dbg(dev, "resuming\n"); + ds_dev_dbg(2, dev, "resuming\n"); if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1149,7 +1267,7 @@ static int pcmcia_dev_resume(struct device * dev) goto out; if (p_dev->device_no == p_dev->func) { - dev_dbg(dev, "requesting configuration\n"); + ds_dev_dbg(2, dev, "requesting configuration\n"); ret = pcmcia_request_configuration(p_dev, &p_dev->conf); if (ret) goto out; @@ -1191,14 +1309,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data) static int pcmcia_bus_resume(struct pcmcia_socket *skt) { - dev_dbg(&skt->dev, "resuming socket %d\n", skt->sock); + ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock); bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); return 0; } static int pcmcia_bus_suspend(struct pcmcia_socket *skt) { - dev_dbg(&skt->dev, "suspending socket %d\n", skt->sock); + ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock); if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_suspend_callback)) { pcmcia_bus_resume(skt); @@ -1230,7 +1348,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) return -ENODEV; } - dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n", + ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n", event, priority, skt); switch (event) { diff --git a/trunk/drivers/pcmcia/i82365.c b/trunk/drivers/pcmcia/i82365.c index c13fd9360511..a4aacb830b80 100644 --- a/trunk/drivers/pcmcia/i82365.c +++ b/trunk/drivers/pcmcia/i82365.c @@ -63,6 +63,21 @@ #include "vg468.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 inline int _check_irq(int irq, int flags) @@ -486,13 +501,13 @@ static irqreturn_t i365_count_irq(int irq, void *dev) { i365_get(irq_sock, I365_CSC); irq_hits++; - pr_debug("i82365: -> hit on irq %d\n", irq); + debug(2, "-> hit on irq %d\n", irq); return IRQ_HANDLED; } static u_int __init test_irq(u_short sock, int irq) { - pr_debug("i82365: testing ISA irq %d\n", irq); + debug(2, " testing ISA irq %d\n", irq); if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan", i365_count_irq) != 0) return 1; @@ -500,7 +515,7 @@ static u_int __init test_irq(u_short sock, int irq) msleep(10); if (irq_hits) { free_irq(irq, i365_count_irq); - pr_debug("i82365: spurious hit!\n"); + debug(2, " spurious hit!\n"); return 1; } @@ -513,7 +528,7 @@ static u_int __init test_irq(u_short sock, int irq) /* mask all interrupts */ i365_set(sock, I365_CSCINT, 0); - pr_debug("i82365: hits = %d\n", irq_hits); + debug(2, " hits = %d\n", irq_hits); return (irq_hits != 1); } @@ -839,7 +854,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev) u_long flags = 0; int handled = 0; - pr_debug("pcic_interrupt(%d)\n", irq); + debug(4, "pcic_interrupt(%d)\n", irq); for (j = 0; j < 20; j++) { active = 0; @@ -863,7 +878,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev) events |= (csc & I365_CSC_READY) ? SS_READY : 0; } ISA_UNLOCK(i, flags); - pr_debug("socket %d event 0x%02x\n", i, events); + debug(2, "socket %d event 0x%02x\n", i, events); if (events) pcmcia_parse_events(&socket[i].socket, events); @@ -875,7 +890,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev) if (j == 20) printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n"); - pr_debug("pcic_interrupt done\n"); + debug(4, "interrupt done\n"); return IRQ_RETVAL(handled); } /* pcic_interrupt */ @@ -917,7 +932,7 @@ static int i365_get_status(u_short sock, u_int *value) } } - pr_debug("GetStatus(%d) = %#4.4x\n", sock, *value); + debug(1, "GetStatus(%d) = %#4.4x\n", sock, *value); return 0; } /* i365_get_status */ @@ -928,7 +943,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state) struct i82365_socket *t = &socket[sock]; u_char reg; - pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " + debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); @@ -1037,7 +1052,7 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io) { u_char map, ioctl; - pr_debug("SetIOMap(%d, %d, %#2.2x, %d ns, " + debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, " "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed, (unsigned long long)io->start, (unsigned long long)io->stop); map = io->map; @@ -1067,7 +1082,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) u_short base, i; u_char map; - pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, " + debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, " "%#x)\n", sock, mem->map, mem->flags, mem->speed, (unsigned long long)mem->res->start, (unsigned long long)mem->res->end, mem->card_start); diff --git a/trunk/drivers/pcmcia/m32r_cfc.c b/trunk/drivers/pcmcia/m32r_cfc.c index 26a621c9e2fc..7dfbee1dcd76 100644 --- a/trunk/drivers/pcmcia/m32r_cfc.c +++ b/trunk/drivers/pcmcia/m32r_cfc.c @@ -38,6 +38,17 @@ #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 */ static int poll_interval = 0; @@ -112,7 +123,7 @@ void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size, unsigned char *bp = (unsigned char *)buf; unsigned long flags; - pr_debug("m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, " + debug(3, "m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, " "size=%u, nmemb=%d, flag=%d\n", sock, port, buf, size, nmemb, flag); @@ -121,7 +132,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); return; } - pr_debug("m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr); + debug(3, "m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr); spin_lock_irqsave(&pcc_lock, flags); /* read Byte */ @@ -137,7 +148,7 @@ void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size, unsigned short *bp = (unsigned short *)buf; unsigned long flags; - pr_debug("m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, " + debug(3, "m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, " "buf=%p, size=%u, nmemb=%d, flag=%d\n", sock, port, buf, size, nmemb, flag); @@ -152,7 +163,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); return; } - pr_debug("m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr); + debug(3, "m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr); spin_lock_irqsave(&pcc_lock, flags); /* read Word */ @@ -168,7 +179,7 @@ void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size, unsigned char *bp = (unsigned char *)buf; unsigned long flags; - pr_debug("m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, " + debug(3, "m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, " "buf=%p, size=%u, nmemb=%d, flag=%d\n", sock, port, buf, size, nmemb, flag); @@ -178,7 +189,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); return; } - pr_debug("m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr); + debug(3, "m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr); spin_lock_irqsave(&pcc_lock, flags); while (nmemb--) @@ -193,7 +204,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size, unsigned short *bp = (unsigned short *)buf; unsigned long flags; - pr_debug("m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, " + debug(3, "m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, " "buf=%p, size=%u, nmemb=%d, flag=%d\n", sock, port, buf, size, nmemb, flag); @@ -215,7 +226,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size, return; } #endif - pr_debug("m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr); + debug(3, "m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr); spin_lock_irqsave(&pcc_lock, flags); while (nmemb--) @@ -251,7 +262,7 @@ static struct timer_list poll_timer; static unsigned int pcc_get(u_short sock, unsigned int reg) { unsigned int val = inw(reg); - pr_debug("m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val); + debug(3, "m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val); return val; } @@ -259,7 +270,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) { outw(data, reg); - pr_debug("m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data); + debug(3, "m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data); } /*====================================================================== @@ -275,14 +286,14 @@ static int __init is_alive(u_short sock) { unsigned int stat; - pr_debug("m32r_cfc: is_alive:\n"); + debug(3, "m32r_cfc: is_alive:\n"); printk("CF: "); stat = pcc_get(sock, (unsigned int)PLD_CFSTS); if (!stat) printk("No "); printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat); - pr_debug("m32r_cfc: is_alive: sock stat is 0x%04x\n", stat); + debug(3, "m32r_cfc: is_alive: sock stat is 0x%04x\n", stat); return 0; } @@ -292,7 +303,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, { pcc_socket_t *t = &socket[pcc_sockets]; - pr_debug("m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, " + debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, " "mapaddr=%#lx, ioaddr=%08x\n", base, irq, mapaddr, ioaddr); @@ -347,7 +358,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, /* eject interrupt */ request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt); #endif - pr_debug("m32r_cfc: enable CFMSK, RDYSEL\n"); + debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n"); pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01); #endif /* CONFIG_PLAT_USRV */ #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) @@ -367,26 +378,26 @@ static irqreturn_t pcc_interrupt(int irq, void *dev) u_int events = 0; int handled = 0; - pr_debug("m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev); + debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev); for (i = 0; i < pcc_sockets; i++) { if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq) continue; handled = 1; - pr_debug("m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ", + debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ", i, irq); events |= SS_DETECT; /* insert or eject */ if (events) pcmcia_parse_events(&socket[i].socket, events); } - pr_debug("m32r_cfc: pcc_interrupt: done\n"); + debug(3, "m32r_cfc: pcc_interrupt: done\n"); return IRQ_RETVAL(handled); } /* pcc_interrupt */ static void pcc_interrupt_wrapper(u_long data) { - pr_debug("m32r_cfc: pcc_interrupt_wrapper:\n"); + debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n"); pcc_interrupt(0, NULL); init_timer(&poll_timer); poll_timer.expires = jiffies + poll_interval; @@ -399,17 +410,17 @@ static int _pcc_get_status(u_short sock, u_int *value) { u_int status; - pr_debug("m32r_cfc: _pcc_get_status:\n"); + debug(3, "m32r_cfc: _pcc_get_status:\n"); status = pcc_get(sock, (unsigned int)PLD_CFSTS); *value = (status) ? SS_DETECT : 0; - pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status); + debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status); #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) if ( status ) { /* enable CF power */ status = inw((unsigned int)PLD_CPCR); if (!(status & PLD_CPCR_CF)) { - pr_debug("m32r_cfc: _pcc_get_status: " + debug(3, "m32r_cfc: _pcc_get_status: " "power on (CPCR=0x%08x)\n", status); status |= PLD_CPCR_CF; outw(status, (unsigned int)PLD_CPCR); @@ -428,7 +439,7 @@ static int _pcc_get_status(u_short sock, u_int *value) status &= ~PLD_CPCR_CF; outw(status, (unsigned int)PLD_CPCR); udelay(100); - pr_debug("m32r_cfc: _pcc_get_status: " + debug(3, "m32r_cfc: _pcc_get_status: " "power off (CPCR=0x%08x)\n", status); } #elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3) @@ -454,13 +465,13 @@ static int _pcc_get_status(u_short sock, u_int *value) /* disable CF power */ pcc_set(sock, (unsigned int)PLD_CPCR, 0); udelay(100); - pr_debug("m32r_cfc: _pcc_get_status: " + debug(3, "m32r_cfc: _pcc_get_status: " "power off (CPCR=0x%08x)\n", status); } #else #error no platform configuration #endif - pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n", + debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n", sock, *value); return 0; } /* _get_status */ @@ -469,7 +480,7 @@ static int _pcc_get_status(u_short sock, u_int *value) static int _pcc_set_socket(u_short sock, socket_state_t *state) { - pr_debug("m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " + debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); @@ -481,39 +492,41 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state) } #endif if (state->flags & SS_RESET) { - pr_debug(":RESET\n"); + debug(3, ":RESET\n"); pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101); }else{ pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100); } if (state->flags & SS_OUTPUT_ENA){ - pr_debug(":OUTPUT_ENA\n"); + debug(3, ":OUTPUT_ENA\n"); /* bit clear */ pcc_set(sock,(unsigned int)PLD_CFBUFCR,0); } else { pcc_set(sock,(unsigned int)PLD_CFBUFCR,1); } +#ifdef CONFIG_PCMCIA_DEBUG if(state->flags & SS_IOCARD){ - pr_debug(":IOCARD"); + debug(3, ":IOCARD"); } if (state->flags & SS_PWR_AUTO) { - pr_debug(":PWR_AUTO"); + debug(3, ":PWR_AUTO"); } if (state->csc_mask & SS_DETECT) - pr_debug(":csc-SS_DETECT"); + debug(3, ":csc-SS_DETECT"); if (state->flags & SS_IOCARD) { if (state->csc_mask & SS_STSCHG) - pr_debug(":STSCHG"); + debug(3, ":STSCHG"); } else { if (state->csc_mask & SS_BATDEAD) - pr_debug(":BATDEAD"); + debug(3, ":BATDEAD"); if (state->csc_mask & SS_BATWARN) - pr_debug(":BATWARN"); + debug(3, ":BATWARN"); if (state->csc_mask & SS_READY) - pr_debug(":READY"); + debug(3, ":READY"); } - pr_debug("\n"); + debug(3, "\n"); +#endif return 0; } /* _set_socket */ @@ -523,7 +536,7 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io) { u_char map; - pr_debug("m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, " + debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, " "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed, (unsigned long long)io->start, (unsigned long long)io->stop); @@ -541,7 +554,7 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem) u_long addr; pcc_socket_t *t = &socket[sock]; - pr_debug("m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, " + debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, " "%#llx, %#x)\n", sock, map, mem->flags, mem->speed, (unsigned long long)mem->static_start, mem->card_start); @@ -627,11 +640,11 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value) unsigned int sock = container_of(s, struct pcc_socket, socket)->number; if (socket[sock].flags & IS_ALIVE) { - dev_dbg(&s->dev, "pcc_get_status: sock(%d) -EINVAL\n", sock); + debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock); *value = 0; return -EINVAL; } - dev_dbg(&s->dev, "pcc_get_status: sock(%d)\n", sock); + debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock); LOCKED(_pcc_get_status(sock, value)); } @@ -640,10 +653,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; if (socket[sock].flags & IS_ALIVE) { - dev_dbg(&s->dev, "pcc_set_socket: sock(%d) -EINVAL\n", sock); + debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock); return -EINVAL; } - dev_dbg(&s->dev, "pcc_set_socket: sock(%d)\n", sock); + debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock); LOCKED(_pcc_set_socket(sock, state)); } @@ -652,10 +665,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; if (socket[sock].flags & IS_ALIVE) { - dev_dbg(&s->dev, "pcc_set_io_map: sock(%d) -EINVAL\n", sock); + debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock); return -EINVAL; } - dev_dbg(&s->dev, "pcc_set_io_map: sock(%d)\n", sock); + debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock); LOCKED(_pcc_set_io_map(sock, io)); } @@ -664,16 +677,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; if (socket[sock].flags & IS_ALIVE) { - dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d) -EINVAL\n", sock); + debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock); return -EINVAL; } - dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d)\n", sock); + debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock); LOCKED(_pcc_set_mem_map(sock, mem)); } static int pcc_init(struct pcmcia_socket *s) { - dev_dbg(&s->dev, "pcc_init()\n"); + debug(3, "m32r_cfc: pcc_init()\n"); return 0; } diff --git a/trunk/drivers/pcmcia/m32r_pcc.c b/trunk/drivers/pcmcia/m32r_pcc.c index 72844c5a6d05..c6524f99ccc3 100644 --- a/trunk/drivers/pcmcia/m32r_pcc.c +++ b/trunk/drivers/pcmcia/m32r_pcc.c @@ -45,6 +45,16 @@ #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 */ static int poll_interval = 0; @@ -348,7 +358,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev) u_int events, active; int handled = 0; - pr_debug("m32r_pcc: pcc_interrupt(%d)\n", irq); + debug(4, "m32r: pcc_interrupt(%d)\n", irq); for (j = 0; j < 20; j++) { active = 0; @@ -359,14 +369,13 @@ static irqreturn_t pcc_interrupt(int irq, void *dev) handled = 1; irc = pcc_get(i, PCIRC); irc >>=16; - pr_debug("m32r_pcc: interrupt: socket %d pcirc 0x%02x ", - i, irc); + debug(2, "m32r-pcc:interrupt: socket %d pcirc 0x%02x ", i, irc); if (!irc) continue; events = (irc) ? SS_DETECT : 0; events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0; - pr_debug("m32r_pcc: event 0x%02x\n", events); + debug(2, " event 0x%02x\n", events); if (events) pcmcia_parse_events(&socket[i].socket, events); @@ -379,7 +388,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev) if (j == 20) printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n"); - pr_debug("m32r_pcc: interrupt done\n"); + debug(4, "m32r-pcc: interrupt done\n"); return IRQ_RETVAL(handled); } /* pcc_interrupt */ @@ -413,7 +422,7 @@ static int _pcc_get_status(u_short sock, u_int *value) status = pcc_get(sock,PCCSIGCR); *value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0; - pr_debug("m32r_pcc: GetStatus(%d) = %#4.4x\n", sock, *value); + debug(3, "m32r-pcc: GetStatus(%d) = %#4.4x\n", sock, *value); return 0; } /* _get_status */ @@ -423,7 +432,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state) { u_long reg = 0; - pr_debug("m32r_pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " + debug(3, "m32r-pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); @@ -439,11 +448,11 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state) } if (state->flags & SS_RESET) { - pr_debug("m32r_pcc: :RESET\n"); + debug(3, ":RESET\n"); reg |= PCCSIGCR_CRST; } if (state->flags & SS_OUTPUT_ENA){ - pr_debug("m32r_pcc: :OUTPUT_ENA\n"); + debug(3, ":OUTPUT_ENA\n"); /* bit clear */ } else { reg |= PCCSIGCR_SEN; @@ -451,26 +460,28 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state) pcc_set(sock,PCCSIGCR,reg); +#ifdef CONFIG_PCMCIA_DEBUG if(state->flags & SS_IOCARD){ - pr_debug("m32r_pcc: :IOCARD"); + debug(3, ":IOCARD"); } if (state->flags & SS_PWR_AUTO) { - pr_debug("m32r_pcc: :PWR_AUTO"); + debug(3, ":PWR_AUTO"); } if (state->csc_mask & SS_DETECT) - pr_debug("m32r_pcc: :csc-SS_DETECT"); + debug(3, ":csc-SS_DETECT"); if (state->flags & SS_IOCARD) { if (state->csc_mask & SS_STSCHG) - pr_debug("m32r_pcc: :STSCHG"); + debug(3, ":STSCHG"); } else { if (state->csc_mask & SS_BATDEAD) - pr_debug("m32r_pcc: :BATDEAD"); + debug(3, ":BATDEAD"); if (state->csc_mask & SS_BATWARN) - pr_debug("m32r_pcc: :BATWARN"); + debug(3, ":BATWARN"); if (state->csc_mask & SS_READY) - pr_debug("m32r_pcc: :READY"); + debug(3, ":READY"); } - pr_debug("m32r_pcc: \n"); + debug(3, "\n"); +#endif return 0; } /* _set_socket */ @@ -480,7 +491,7 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io) { u_char map; - pr_debug("m32r_pcc: SetIOMap(%d, %d, %#2.2x, %d ns, " + debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, " "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed, (unsigned long long)io->start, (unsigned long long)io->stop); @@ -504,7 +515,7 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem) #endif #endif - pr_debug("m32r_pcc: SetMemMap(%d, %d, %#2.2x, %d ns, " + debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, " "%#llx, %#x)\n", sock, map, mem->flags, mem->speed, (unsigned long long)mem->static_start, mem->card_start); @@ -651,7 +662,7 @@ static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem) static int pcc_init(struct pcmcia_socket *s) { - pr_debug("m32r_pcc: init call\n"); + debug(4, "m32r-pcc: init call\n"); return 0; } diff --git a/trunk/drivers/pcmcia/m8xx_pcmcia.c b/trunk/drivers/pcmcia/m8xx_pcmcia.c index 7f79c4e169ae..403559ba49dd 100644 --- a/trunk/drivers/pcmcia/m8xx_pcmcia.c +++ b/trunk/drivers/pcmcia/m8xx_pcmcia.c @@ -64,6 +64,14 @@ #include #include +#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_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args) @@ -557,7 +565,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev) unsigned int i, events, pscr, pipr, per; pcmconf8xx_t *pcmcia = socket[0].pcmcia; - pr_debug("m8xx_pcmcia: Interrupt!\n"); + dprintk("Interrupt!\n"); /* get interrupt sources */ pscr = in_be32(&pcmcia->pcmc_pscr); @@ -606,7 +614,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev) /* call the handler */ - pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, " + dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, " "pipr = 0x%08x\n", i, events, pscr, pipr); if (events) { @@ -633,7 +641,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev) /* clear the interrupt sources */ out_be32(&pcmcia->pcmc_pscr, pscr); - pr_debug("m8xx_pcmcia: Interrupt done.\n"); + dprintk("Interrupt done.\n"); return IRQ_HANDLED; } @@ -807,7 +815,7 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value) }; } - pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x\n", lsock, *value); + dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value); return 0; } @@ -820,7 +828,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state) unsigned long flags; pcmconf8xx_t *pcmcia = socket[0].pcmcia; - pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " + dprintk("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); @@ -966,7 +974,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_BASE (PCMCIA_IO_WIN_BASE + io->start) - pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, " + dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, " "%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags, io->speed, (unsigned long long)io->start, (unsigned long long)io->stop); @@ -980,7 +988,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) if (io->flags & MAP_ACTIVE) { - pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE\n"); + dprintk("io->flags & MAP_ACTIVE\n"); winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO) + (lsock * PCMCIA_IO_WIN_NO) + io->map; @@ -1010,8 +1018,8 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) out_be32(&w->or, reg); - pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at " - "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or); + dprintk("Socket %u: Mapped io window %u at %#8.8x, " + "OR = %#8.8x.\n", lsock, io->map, w->br, w->or); } else { /* shutdown IO window */ winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO) @@ -1025,14 +1033,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->br, 0); /* turn off base address */ - pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at " - "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or); + dprintk("Socket %u: Unmapped io window %u at %#8.8x, " + "OR = %#8.8x.\n", lsock, io->map, w->br, w->or); } /* copy the struct and modify the copy */ s->io_win[io->map] = *io; s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE); - pr_debug("m8xx_pcmcia: SetIOMap exit\n"); + dprintk("SetIOMap exit\n"); return 0; } @@ -1047,7 +1055,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, unsigned int reg, winnr; pcmconf8xx_t *pcmcia = s->pcmcia; - pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, " + dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, " "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags, mem->speed, (unsigned long long)mem->static_start, mem->card_start); @@ -1090,7 +1098,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, out_be32(&w->or, reg); - pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, " + dprintk("Socket %u: Mapped memory window %u at %#8.8x, " "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or); if (mem->flags & MAP_ACTIVE) { @@ -1100,7 +1108,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, + mem->card_start; } - pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, " + dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, " "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags, mem->speed, (unsigned long long)mem->static_start, mem->card_start); @@ -1121,7 +1129,7 @@ static int m8xx_sock_init(struct pcmcia_socket *sock) pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; - pr_debug("m8xx_pcmcia: sock_init(%d)\n", s); + dprintk("sock_init(%d)\n", s); m8xx_set_socket(sock, &dead_socket); for (i = 0; i < PCMCIA_IO_WIN_NO; i++) { diff --git a/trunk/drivers/pcmcia/o2micro.h b/trunk/drivers/pcmcia/o2micro.h index 624442fc0d35..72188c462c9c 100644 --- a/trunk/drivers/pcmcia/o2micro.h +++ b/trunk/drivers/pcmcia/o2micro.h @@ -30,6 +30,28 @@ #ifndef _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 */ #define O2_MUX_CONTROL 0x90 /* 32 bit */ diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index c4d7908fa37f..30cf71d2ee23 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -58,6 +58,17 @@ typedef struct 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, unsigned int function) { @@ -218,61 +229,6 @@ static int pcmcia_adjust_resource_info(adjust_t *adj) 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 * * Get the current socket state bits. We don't support the latched @@ -475,7 +431,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) if (!s) return -EINVAL; - pr_debug("bind_request(%d, '%s')\n", s->sock, + ds_dbg(2, "bind_request(%d, '%s')\n", s->sock, (char *)bind_info->dev_info); p_drv = get_pcmcia_driver(&bind_info->dev_info); @@ -667,7 +623,7 @@ static int ds_open(struct inode *inode, struct file *file) static int warning_printed = 0; int ret = 0; - pr_debug("ds_open(socket %d)\n", i); + ds_dbg(0, "ds_open(socket %d)\n", i); lock_kernel(); s = pcmcia_get_socket_by_nr(i); @@ -729,7 +685,7 @@ static int ds_release(struct inode *inode, struct file *file) struct pcmcia_socket *s; user_info_t *user, **link; - pr_debug("ds_release(socket %d)\n", iminor(inode)); + ds_dbg(0, "ds_release(socket %d)\n", iminor(inode)); user = file->private_data; if (CHECK_USER(user)) @@ -763,7 +719,7 @@ static ssize_t ds_read(struct file *file, char __user *buf, user_info_t *user; int ret; - pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode)); + ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode)); if (count < 4) return -EINVAL; @@ -788,7 +744,7 @@ static ssize_t ds_read(struct file *file, char __user *buf, static ssize_t ds_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode)); + ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode)); if (count != 4) return -EINVAL; @@ -806,7 +762,7 @@ static u_int ds_poll(struct file *file, poll_table *wait) struct pcmcia_socket *s; user_info_t *user; - pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode)); + ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode)); user = file->private_data; if (CHECK_USER(user)) @@ -834,7 +790,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, ds_ioctl_arg_t *buf; user_info_t *user; - pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg); + ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg); user = file->private_data; if (CHECK_USER(user)) @@ -853,13 +809,13 @@ static int ds_ioctl(struct inode * inode, struct file * file, if (cmd & IOC_IN) { if (!access_ok(VERIFY_READ, uarg, size)) { - pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT); + ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT); return -EFAULT; } } if (cmd & IOC_OUT) { if (!access_ok(VERIFY_WRITE, uarg, size)) { - pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT); + ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT); return -EFAULT; } } @@ -971,15 +927,15 @@ static int ds_ioctl(struct inode * inode, struct file * file, goto free_out; break; case DS_GET_FIRST_WINDOW: - ret = pcmcia_get_window(s, &buf->win_info.handle, 1, + ret = pcmcia_get_window(s, &buf->win_info.handle, 0, &buf->win_info.window); break; case DS_GET_NEXT_WINDOW: ret = pcmcia_get_window(s, &buf->win_info.handle, - buf->win_info.handle + 1, &buf->win_info.window); + buf->win_info.handle->index + 1, &buf->win_info.window); break; case DS_GET_MEM_PAGE: - ret = pcmcia_get_mem_page(s, buf->win_info.handle, + ret = pcmcia_get_mem_page(buf->win_info.handle, &buf->win_info.map); break; case DS_REPLACE_CIS: @@ -1006,7 +962,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, } if ((err == 0) && (ret != 0)) { - pr_debug("ds_ioctl: ret = %d\n", ret); + ds_dbg(2, "ds_ioctl: ret = %d\n", ret); switch (ret) { case -ENODEV: case -EINVAL: diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index a8bf8c1b45ed..d919e96c0afd 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -44,6 +43,21 @@ static u8 pcmcia_used_irq[NR_IRQS]; #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 * * Special stuff for managing IO windows, because they are scarce @@ -58,14 +72,14 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, align = (*base) ? (lines ? 1<dev, "odd IO request: num %#x align %#x\n", + ds_dbg(s, 0, "odd IO request: num %#x align %#x\n", num, align); align = 0; } else while (align && (align < num)) align <<= 1; } if (*base & ~(align-1)) { - dev_dbg(&s->dev, "odd IO request: base %#x align %#x\n", + ds_dbg(s, 0, "odd IO request: base %#x align %#x\n", *base, align); align = 0; } @@ -159,10 +173,8 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, s = p_dev->socket; c = p_dev->function_config; - if (!(c->state & CONFIG_LOCKED)) { - dev_dbg(&s->dev, "Configuration isnt't locked\n"); + if (!(c->state & CONFIG_LOCKED)) return -EACCES; - } addr = (c->ConfigBase + reg->Offset) >> 1; @@ -176,7 +188,6 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, pcmcia_write_cis_mem(s, 1, addr, 1, &val); break; default: - dev_dbg(&s->dev, "Invalid conf register request\n"); return -EINVAL; break; } @@ -185,21 +196,68 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, EXPORT_SYMBOL(pcmcia_access_configuration_register); -int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, - memreq_t *req) +/** pcmcia_get_window + */ +int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, + int idx, win_req_t *req) { - struct pcmcia_socket *s = p_dev->socket; + window_t *win; + int w; + + if (!s || !(s->state & SOCKET_PRESENT)) + return -ENODEV; + for (w = idx; 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->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); + - wh--; - if (wh >= MAX_WIN) +/** 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) { - dev_dbg(&s->dev, "failure: requested page is zero\n"); + ds_dbg(s, 0, "failure: requested page is zero\n"); return -EINVAL; } - s->win[wh].card_start = req->CardOffset; - if (s->ops->set_mem_map(s, &s->win[wh]) != 0) { - dev_dbg(&s->dev, "failed to set_mem_map\n"); + win->ctl.card_start = req->CardOffset; + if (s->ops->set_mem_map(s, &win->ctl) != 0) { + ds_dbg(s, 0, "failed to set_mem_map\n"); return -EIO; } return 0; @@ -220,14 +278,10 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, s = p_dev->socket; c = p_dev->function_config; - if (!(s->state & SOCKET_PRESENT)) { - dev_dbg(&s->dev, "No card present\n"); + if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - } - if (!(c->state & CONFIG_LOCKED)) { - dev_dbg(&s->dev, "Configuration isnt't locked\n"); + if (!(c->state & CONFIG_LOCKED)) return -EACCES; - } if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { if (mod->Attributes & CONF_ENABLE_IRQ) { @@ -241,7 +295,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, } if (mod->Attributes & CONF_VCC_CHANGE_VALID) { - dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); + ds_dbg(s, 0, "changing Vcc is not allowed at this time\n"); return -EINVAL; } @@ -249,7 +303,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { if (mod->Vpp1 != mod->Vpp2) { - dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); + ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n"); return -EINVAL; } s->socket.Vpp = mod->Vpp1; @@ -260,7 +314,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, } } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { - dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); + ds_dbg(s, 0, "changing Vcc is not allowed at this time\n"); return -EINVAL; } @@ -371,11 +425,11 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) if (c->state & CONFIG_LOCKED) return -EACCES; if (c->irq.Attributes != req->Attributes) { - dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n"); + ds_dbg(s, 0, "IRQ attributes must match assigned ones\n"); return -EINVAL; } if (s->irq.AssignedIRQ != req->AssignedIRQ) { - dev_dbg(&s->dev, "IRQ must match assigned one\n"); + ds_dbg(s, 0, "IRQ must match assigned one\n"); return -EINVAL; } if (--s->irq.Config == 0) { @@ -383,8 +437,8 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) s->irq.AssignedIRQ = 0; } - if (req->Handler) { - free_irq(req->AssignedIRQ, p_dev->priv); + if (req->Attributes & IRQ_HANDLE_PRESENT) { + free_irq(req->AssignedIRQ, req->Instance); } #ifdef CONFIG_PCMCIA_PROBE @@ -395,34 +449,30 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) } /* pcmcia_release_irq */ -int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) +int pcmcia_release_window(window_handle_t win) { - struct pcmcia_socket *s = p_dev->socket; - pccard_mem_map *win; + struct pcmcia_socket *s; - wh--; - if (wh >= MAX_WIN) + if ((win == NULL) || (win->magic != WINDOW_MAGIC)) return -EINVAL; - - win = &s->win[wh]; - - if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) { - dev_dbg(&s->dev, "not releasing unknown window\n"); + s = win->sock; + if (!(win->handle->_win & CLIENT_WIN_REQ(win->index))) return -EINVAL; - } /* Shut down memory window */ - win->flags &= ~MAP_ACTIVE; - s->ops->set_mem_map(s, win); - s->state &= ~SOCKET_WIN_REQ(wh); + win->ctl.flags &= ~MAP_ACTIVE; + s->ops->set_mem_map(s, &win->ctl); + s->state &= ~SOCKET_WIN_REQ(win->index); /* Release system memory */ - if (win->res) { - release_resource(win->res); - kfree(win->res); - win->res = NULL; + if (win->ctl.res) { + release_resource(win->ctl.res); + kfree(win->ctl.res); + win->ctl.res = NULL; } - p_dev->_win &= ~CLIENT_WIN_REQ(wh); + win->handle->_win &= ~CLIENT_WIN_REQ(win->index); + + win->magic = 0; return 0; } /* pcmcia_release_window */ @@ -442,14 +492,12 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, return -ENODEV; if (req->IntType & INT_CARDBUS) { - dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n"); + ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n"); return -EINVAL; } c = p_dev->function_config; - if (c->state & CONFIG_LOCKED) { - dev_dbg(&s->dev, "Configuration is locked\n"); + if (c->state & CONFIG_LOCKED) return -EACCES; - } /* Do power control. We don't allow changes in Vcc. */ s->socket.Vpp = req->Vpp; @@ -561,44 +609,40 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) struct pcmcia_socket *s = p_dev->socket; config_t *c; - if (!(s->state & SOCKET_PRESENT)) { - dev_dbg(&s->dev, "No card present\n"); + if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - } if (!req) return -EINVAL; c = p_dev->function_config; - if (c->state & CONFIG_LOCKED) { - dev_dbg(&s->dev, "Configuration is locked\n"); + if (c->state & CONFIG_LOCKED) return -EACCES; - } if (c->state & CONFIG_IO_REQ) { - dev_dbg(&s->dev, "IO already configured\n"); + ds_dbg(s, 0, "IO already configured\n"); return -EBUSY; } if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) { - dev_dbg(&s->dev, "bad attribute setting for IO region 1\n"); + ds_dbg(s, 0, "bad attribute setting for IO region 1\n"); return -EINVAL; } if ((req->NumPorts2 > 0) && (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) { - dev_dbg(&s->dev, "bad attribute setting for IO region 2\n"); + ds_dbg(s, 0, "bad attribute setting for IO region 2\n"); return -EINVAL; } - dev_dbg(&s->dev, "trying to allocate resource 1\n"); + ds_dbg(s, 1, "trying to allocate resource 1\n"); if (alloc_io_space(s, req->Attributes1, &req->BasePort1, req->NumPorts1, req->IOAddrLines)) { - dev_dbg(&s->dev, "allocation of resource 1 failed\n"); + ds_dbg(s, 0, "allocation of resource 1 failed\n"); return -EBUSY; } if (req->NumPorts2) { - dev_dbg(&s->dev, "trying to allocate resource 2\n"); + ds_dbg(s, 1, "trying to allocate resource 2\n"); if (alloc_io_space(s, req->Attributes2, &req->BasePort2, req->NumPorts2, req->IOAddrLines)) { - dev_dbg(&s->dev, "allocation of resource 2 failed\n"); + ds_dbg(s, 0, "allocation of resource 2 failed\n"); release_io_space(s, req->BasePort1, req->NumPorts1); return -EBUSY; } @@ -636,17 +680,13 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) int ret = -EINVAL, irq = 0; int type; - if (!(s->state & SOCKET_PRESENT)) { - dev_dbg(&s->dev, "No card present\n"); + if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - } c = p_dev->function_config; - if (c->state & CONFIG_LOCKED) { - dev_dbg(&s->dev, "Configuration is locked\n"); + if (c->state & CONFIG_LOCKED) return -EACCES; - } if (c->state & CONFIG_IRQ_REQ) { - dev_dbg(&s->dev, "IRQ already configured\n"); + ds_dbg(s, 0, "IRQ already configured\n"); return -EBUSY; } @@ -664,7 +704,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) /* if the underlying IRQ infrastructure allows for it, only allocate * the IRQ, but do not enable it */ - if (!(req->Handler)) + if (!(req->Attributes & IRQ_HANDLE_PRESENT)) type |= IRQ_NOAUTOEN; #endif /* IRQ_NOAUTOEN */ @@ -674,7 +714,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) } else { int try; u32 mask = s->irq_mask; - void *data = p_dev; /* something unique to this device */ + void *data = &p_dev->dev.driver; /* something unique to this device */ for (try = 0; try < 64; try++) { irq = try % 32; @@ -691,12 +731,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 * marked as used by the kernel resource management core */ ret = request_irq(irq, - (req->Handler) ? req->Handler : test_action, + (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action, type, p_dev->devname, - (req->Handler) ? p_dev->priv : data); + (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data); if (!ret) { - if (!req->Handler) + if (!(req->Attributes & IRQ_HANDLE_PRESENT)) free_irq(irq, data); break; } @@ -705,22 +745,17 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) #endif /* only assign PCI irq if no IRQ already assigned */ if (ret && !s->irq.AssignedIRQ) { - if (!s->pci_irq) { - dev_printk(KERN_INFO, &s->dev, "no IRQ found\n"); + if (!s->pci_irq) return ret; - } type = IRQF_SHARED; irq = s->pci_irq; } - if (ret && req->Handler) { + if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) { ret = request_irq(irq, req->Handler, type, - p_dev->devname, p_dev->priv); - if (ret) { - dev_printk(KERN_INFO, &s->dev, - "request_irq() failed\n"); + p_dev->devname, req->Instance); + if (ret) return ret; - } } /* Make sure the fact the request type was overridden is passed back */ @@ -752,19 +787,17 @@ EXPORT_SYMBOL(pcmcia_request_irq); * Request_window() establishes a mapping between card 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; - pccard_mem_map *win; + struct pcmcia_socket *s = (*p_dev)->socket; + window_t *win; u_long align; int w; - if (!(s->state & SOCKET_PRESENT)) { - dev_dbg(&s->dev, "No card present\n"); + if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - } if (req->Attributes & (WIN_PAGED | WIN_SHARED)) { - dev_dbg(&s->dev, "bad attribute setting for iomem region\n"); + ds_dbg(s, 0, "bad attribute setting for iomem region\n"); return -EINVAL; } @@ -775,12 +808,12 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha (req->Attributes & WIN_STRICT_ALIGN)) ? req->Size : s->map_size); if (req->Size & (s->map_size-1)) { - dev_dbg(&s->dev, "invalid map size\n"); + ds_dbg(s, 0, "invalid map size\n"); return -EINVAL; } if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || (req->Base & (align-1))) { - dev_dbg(&s->dev, "invalid base address\n"); + ds_dbg(s, 0, "invalid base address\n"); return -EINVAL; } if (req->Base) @@ -790,48 +823,52 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha for (w = 0; w < MAX_WIN; w++) if (!(s->state & SOCKET_WIN_REQ(w))) break; if (w == MAX_WIN) { - dev_dbg(&s->dev, "all windows are used already\n"); + ds_dbg(s, 0, "all windows are used already\n"); return -EINVAL; } 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)) { - win->res = pcmcia_find_mem_region(req->Base, req->Size, align, + win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align, (req->Attributes & WIN_MAP_BELOW_1MB), s); - if (!win->res) { - dev_dbg(&s->dev, "allocating mem region failed\n"); + if (!win->ctl.res) { + ds_dbg(s, 0, "allocating mem region failed\n"); return -EINVAL; } } - p_dev->_win |= CLIENT_WIN_REQ(w); + (*p_dev)->_win |= CLIENT_WIN_REQ(w); /* Configure the socket controller */ - win->map = w+1; - win->flags = 0; - win->speed = req->AccessSpeed; + win->ctl.map = w+1; + win->ctl.flags = 0; + win->ctl.speed = req->AccessSpeed; if (req->Attributes & WIN_MEMORY_TYPE) - win->flags |= MAP_ATTRIB; + win->ctl.flags |= MAP_ATTRIB; if (req->Attributes & WIN_ENABLE) - win->flags |= MAP_ACTIVE; + win->ctl.flags |= MAP_ACTIVE; if (req->Attributes & WIN_DATA_WIDTH_16) - win->flags |= MAP_16BIT; + win->ctl.flags |= MAP_16BIT; if (req->Attributes & WIN_USE_WAIT) - win->flags |= MAP_USE_WAIT; - win->card_start = 0; - if (s->ops->set_mem_map(s, win) != 0) { - dev_dbg(&s->dev, "failed to set memory mapping\n"); + win->ctl.flags |= MAP_USE_WAIT; + win->ctl.card_start = 0; + if (s->ops->set_mem_map(s, &win->ctl) != 0) { + ds_dbg(s, 0, "failed to set memory mapping\n"); return -EIO; } s->state |= SOCKET_WIN_REQ(w); /* Return window handle */ if (s->features & SS_CAP_STATIC_MAP) { - req->Base = win->static_start; + req->Base = win->ctl.static_start; } else { - req->Base = win->res->start; + req->Base = win->ctl.res->start; } - *wh = w + 1; + *wh = win; return 0; } /* pcmcia_request_window */ @@ -842,45 +879,18 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) { pcmcia_release_io(p_dev, &p_dev->io); pcmcia_release_irq(p_dev, &p_dev->irq); if (p_dev->win) - pcmcia_release_window(p_dev, p_dev->win); + pcmcia_release_window(p_dev->win); } EXPORT_SYMBOL(pcmcia_disable_device); struct pcmcia_cfg_mem { - 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); + tuple_t tuple; cisparse_t parse; + u8 buf[256]; 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 * @p_dev: the struct pcmcia_device which we need to loop for. @@ -903,174 +913,48 @@ int pcmcia_loop_config(struct pcmcia_device *p_dev, void *priv_data) { struct pcmcia_cfg_mem *cfg_mem; + + tuple_t *tuple; int ret; + unsigned int vcc; cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); if (cfg_mem == NULL) return -ENOMEM; - cfg_mem->p_dev = p_dev; - cfg_mem->conf_check = conf_check; - cfg_mem->priv_data = priv_data; + /* get the current Vcc setting */ + vcc = p_dev->socket->socket.Vcc; - ret = pccard_loop_tuple(p_dev->socket, p_dev->func, - CISTPL_CFTABLE_ENTRY, &cfg_mem->parse, - cfg_mem, pcmcia_do_loop_config); + tuple = &cfg_mem->tuple; + tuple->TupleData = cfg_mem->buf; + tuple->TupleDataMax = 255; + tuple->TupleOffset = 0; + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple->Attributes = 0; - kfree(cfg_mem); - return ret; -} -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}; + ret = pcmcia_get_first_tuple(p_dev, tuple); + while (!ret) { + cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry; - return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL, - &loop, pcmcia_do_loop_tuple); -}; -EXPORT_SYMBOL(pcmcia_loop_tuple); + if (pcmcia_get_tuple_data(p_dev, tuple)) + goto next_entry; + if (pcmcia_parse_tuple(tuple, &cfg_mem->parse)) + goto next_entry; -struct pcmcia_loop_get { - size_t len; - cisdata_t **buf; -}; + /* default values */ + p_dev->conf.ConfigIndex = cfg->index; + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + cfg_mem->dflt = *cfg; -/** - * 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; -}; + ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data); + if (!ret) + break; -/** - * 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; +next_entry: + ret = pcmcia_get_next_tuple(p_dev, tuple); } - 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); - + return ret; +} +EXPORT_SYMBOL(pcmcia_loop_config); diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index e1741cd875aa..70a33468bcd0 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -213,8 +213,7 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev) if (csc & I365_CSC_DETECT) { events |= SS_DETECT; - dev_vdbg(&socket[i].socket.dev, - "Card detected in socket %i!\n", i); + dprintk("Card detected in socket %i!\n", i); } if (indirect_read(&socket[i], I365_INTCTL) @@ -332,11 +331,11 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */ if (state->flags & SS_PWR_AUTO) { - dev_dbg(&sock->dev, "Auto power\n"); + dprintk("Auto power\n"); reg |= I365_PWR_AUTO; /* automatic power mngmnt */ } if (state->flags & SS_OUTPUT_ENA) { - dev_dbg(&sock->dev, "Power Enabled\n"); + dprintk("Power Enabled\n"); reg |= I365_PWR_OUT; /* enable power */ } @@ -344,44 +343,40 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) case 0: break; case 33: - dev_dbg(&sock->dev, - "setting voltage to Vcc to 3.3V on socket %i\n", + dprintk("setting voltage to Vcc to 3.3V on socket %i\n", socket->number); reg |= I365_VCC_5V; indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); break; case 50: - dev_dbg(&sock->dev, - "setting voltage to Vcc to 5V on socket %i\n", + dprintk("setting voltage to Vcc to 5V on socket %i\n", socket->number); reg |= I365_VCC_5V; indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V); break; default: - dev_dbg(&sock->dev, - "pd6729_set_socket called with invalid VCC power " - "value: %i\n", state->Vcc); + dprintk("pd6729: pd6729_set_socket called with " + "invalid VCC power value: %i\n", + state->Vcc); return -EINVAL; } switch (state->Vpp) { case 0: - dev_dbg(&sock->dev, "not setting Vpp on socket %i\n", - socket->number); + dprintk("not setting Vpp on socket %i\n", socket->number); break; case 33: case 50: - dev_dbg(&sock->dev, "setting Vpp to Vcc for socket %i\n", - socket->number); + dprintk("setting Vpp to Vcc for socket %i\n", socket->number); reg |= I365_VPP1_5V; break; case 120: - dev_dbg(&sock->dev, "setting Vpp to 12.0\n"); + dprintk("setting Vpp to 12.0\n"); reg |= I365_VPP1_12V; break; default: - dev_dbg(&sock->dev, "pd6729: pd6729_set_socket called with " - "invalid VPP power value: %i\n", state->Vpp); + dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i\n", + state->Vpp); return -EINVAL; } @@ -443,7 +438,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock, /* Check error conditions */ if (map > 1) { - dev_dbg(&sock->dev, "pd6729_set_io_map with invalid map\n"); + dprintk("pd6729_set_io_map with invalid map"); return -EINVAL; } @@ -451,7 +446,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock, if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map)) indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map)); - /* dev_dbg(&sock->dev, "set_io_map: Setting range to %x - %x\n", + /* dprintk("set_io_map: Setting range to %x - %x\n", io->start, io->stop);*/ /* write the new values */ @@ -483,12 +478,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock, map = mem->map; if (map > 4) { - dev_warn(&sock->dev, "invalid map requested\n"); + printk("pd6729_set_mem_map: invalid map"); return -EINVAL; } if ((mem->res->start > mem->res->end) || (mem->speed > 1000)) { - dev_warn(&sock->dev, "invalid invalid address / speed\n"); + printk("pd6729_set_mem_map: invalid address / speed"); return -EINVAL; } @@ -534,12 +529,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock, if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT; if (mem->flags & MAP_ATTRIB) { - /* dev_dbg(&sock->dev, "requesting attribute memory for " - "socket %i\n", socket->number);*/ + /* dprintk("requesting attribute memory for socket %i\n", + socket->number);*/ i |= I365_MEM_REG; } else { - /* dev_dbg(&sock->dev, "requesting normal memory for " - "socket %i\n", socket->number);*/ + /* dprintk("requesting normal memory for socket %i\n", + socket->number);*/ } indirect_write16(socket, base + I365_W_OFF, i); @@ -582,7 +577,7 @@ static struct pccard_operations pd6729_operations = { static irqreturn_t pd6729_test(int irq, void *dev) { - pr_devel("-> hit on irq %d\n", irq); + dprintk("-> hit on irq %d\n", irq); return IRQ_HANDLED; } @@ -647,13 +642,13 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, goto err_out_free_mem; if (!pci_resource_start(dev, 0)) { - dev_warn(&dev->dev, "refusing to load the driver as the " - "io_base is NULL.\n"); + printk(KERN_INFO "pd6729: refusing to load the driver " + "as the io_base is 0.\n"); goto err_out_free_mem; } - dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx " - "on irq %d\n", + printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge " + "at 0x%llx on irq %d\n", (unsigned long long)pci_resource_start(dev, 0), dev->irq); /* * Since we have no memory BARs some firmware may not @@ -661,14 +656,14 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, */ pci_read_config_byte(dev, PCI_COMMAND, &configbyte); if (!(configbyte & PCI_COMMAND_MEMORY)) { - dev_dbg(&dev->dev, "pd6729: Enabling PCI_COMMAND_MEMORY.\n"); + printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n"); configbyte |= PCI_COMMAND_MEMORY; pci_write_config_byte(dev, PCI_COMMAND, configbyte); } ret = pci_request_regions(dev, "pd6729"); if (ret) { - dev_warn(&dev->dev, "pci request region failed.\n"); + printk(KERN_INFO "pd6729: pci request region failed.\n"); goto err_out_disable; } @@ -677,7 +672,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, mask = pd6729_isa_scan(); if (irq_mode == 0 && mask == 0) { - dev_warn(&dev->dev, "no ISA interrupt is available.\n"); + printk(KERN_INFO "pd6729: no ISA interrupt is available.\n"); goto err_out_free_res; } @@ -702,8 +697,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, /* Register the interrupt handler */ if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED, "pd6729", socket))) { - dev_err(&dev->dev, "Failed to register irq %d\n", - dev->irq); + printk(KERN_ERR "pd6729: Failed to register irq %d, " + "aborting\n", dev->irq); goto err_out_free_res; } } else { @@ -718,7 +713,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, for (i = 0; i < MAX_SOCKETS; i++) { ret = pcmcia_register_socket(&socket[i].socket); if (ret) { - dev_warn(&dev->dev, "pcmcia_register_socket failed.\n"); + printk(KERN_INFO "pd6729: pcmcia_register_socket " + "failed.\n"); for (j = 0; j < i ; j++) pcmcia_unregister_socket(&socket[j].socket); goto err_out_free_res2; diff --git a/trunk/drivers/pcmcia/pd6729.h b/trunk/drivers/pcmcia/pd6729.h index 41418d394c55..f392e458cdfd 100644 --- a/trunk/drivers/pcmcia/pd6729.h +++ b/trunk/drivers/pcmcia/pd6729.h @@ -1,6 +1,13 @@ #ifndef _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 */ #define I365_DF_VS1 0x40 /* DF-step Voltage Sense */ #define I365_DF_VS2 0x80 diff --git a/trunk/drivers/pcmcia/pxa2xx_base.c b/trunk/drivers/pcmcia/pxa2xx_base.c index 84dde7768ad5..0e35acb1366b 100644 --- a/trunk/drivers/pcmcia/pxa2xx_base.c +++ b/trunk/drivers/pcmcia/pxa2xx_base.c @@ -228,43 +228,9 @@ static const char *skt_names[] = { #define SKT_DEV_INFO_SIZE(n) \ (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 i, ret = 0; + int i, ret; struct pcmcia_low_level *ops; struct skt_dev_info *sinfo; struct soc_pcmcia_socket *skt; @@ -274,8 +240,6 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev) ops = (struct pcmcia_low_level *)dev->platform_data; - pxa2xx_drv_pcmcia_ops(ops); - sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); if (!sinfo) return -ENOMEM; @@ -286,25 +250,40 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev) for (i = 0; i < ops->nr; i++) { skt = &sinfo->skt[i]; - skt->nr = ops->first + i; - skt->ops = ops; - skt->socket.owner = ops->owner; - skt->socket.dev.parent = dev; - skt->socket.pci_irq = NO_IRQ; + skt->nr = ops->first + i; + skt->irq = NO_IRQ; + + 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; - ret = pxa2xx_drv_pcmcia_add_one(skt); - if (ret) - break; + 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; } - if (ret) { - while (--i >= 0) - soc_pcmcia_remove_one(&sinfo->skt[i]); - kfree(sinfo); - } else { + /* 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 + + ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo); + + if (!ret) pxa2xx_configure_sockets(dev); - dev_set_drvdata(dev, sinfo); - } return ret; } @@ -318,16 +297,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) static int pxa2xx_drv_pcmcia_remove(struct platform_device *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; + return soc_common_drv_pcmcia_remove(&dev->dev); } static int pxa2xx_drv_pcmcia_suspend(struct device *dev) diff --git a/trunk/drivers/pcmcia/pxa2xx_base.h b/trunk/drivers/pcmcia/pxa2xx_base.h index cb5efaec886f..235d681652c3 100644 --- a/trunk/drivers/pcmcia/pxa2xx_base.h +++ b/trunk/drivers/pcmcia/pxa2xx_base.h @@ -1,6 +1,3 @@ /* temporary measure */ 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); - diff --git a/trunk/drivers/pcmcia/pxa2xx_cm_x255.c b/trunk/drivers/pcmcia/pxa2xx_cm_x255.c index 05913d0bbdbe..5143a760153b 100644 --- a/trunk/drivers/pcmcia/pxa2xx_cm_x255.c +++ b/trunk/drivers/pcmcia/pxa2xx_cm_x255.c @@ -44,7 +44,7 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) return ret; gpio_direction_output(GPIO_PCMCIA_RESET, 0); - skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; + skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); if (!ret) gpio_free(GPIO_PCMCIA_RESET); diff --git a/trunk/drivers/pcmcia/pxa2xx_cm_x270.c b/trunk/drivers/pcmcia/pxa2xx_cm_x270.c index 5662646b84da..a7b943d01e34 100644 --- a/trunk/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/trunk/drivers/pcmcia/pxa2xx_cm_x270.c @@ -38,7 +38,7 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) return ret; gpio_direction_output(GPIO_PCMCIA_RESET, 0); - skt->socket.pci_irq = PCMCIA_S0_RDYINT; + skt->irq = PCMCIA_S0_RDYINT; ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); if (!ret) gpio_free(GPIO_PCMCIA_RESET); diff --git a/trunk/drivers/pcmcia/pxa2xx_e740.c b/trunk/drivers/pcmcia/pxa2xx_e740.c index 8bfbd4dca131..d09c0dc4a31a 100644 --- a/trunk/drivers/pcmcia/pxa2xx_e740.c +++ b/trunk/drivers/pcmcia/pxa2xx_e740.c @@ -38,7 +38,7 @@ static struct pcmcia_irqs cd_irqs[] = { static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - skt->socket.pci_irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) : + skt->irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) : IRQ_GPIO(GPIO_E740_PCMCIA_RDY1); return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); diff --git a/trunk/drivers/pcmcia/pxa2xx_lubbock.c b/trunk/drivers/pcmcia/pxa2xx_lubbock.c index b9f8c8fb42bd..6cbb1b1f7cfd 100644 --- a/trunk/drivers/pcmcia/pxa2xx_lubbock.c +++ b/trunk/drivers/pcmcia/pxa2xx_lubbock.c @@ -32,7 +32,6 @@ static int lubbock_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, misc_mask, misc_set; int ret = 0; @@ -150,7 +149,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, if (ret == 0) { lubbock_set_misc_wr(misc_mask, misc_set); - sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); + sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); } #if 1 @@ -176,7 +175,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, * Switch to 5V, Configure socket with 5V voltage */ lubbock_set_misc_wr(misc_mask, 0); - sa1111_set_io(s->dev, pa_dwr_mask, 0); + sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0); /* * It takes about 100ms to turn off Vcc. @@ -201,8 +200,12 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static struct pcmcia_low_level lubbock_pcmcia_ops = { .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, .socket_init = sa1111_pcmcia_socket_init, + .socket_suspend = sa1111_pcmcia_socket_suspend, .first = 0, .nr = 2, }; @@ -225,9 +228,8 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev) /* Set CF Socket 1 power to standby mode. */ lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); - pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); - ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, - pxa2xx_drv_pcmcia_add_one); + sadev->dev.platform_data = &lubbock_pcmcia_ops; + ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev); } return ret; diff --git a/trunk/drivers/pcmcia/pxa2xx_mainstone.c b/trunk/drivers/pcmcia/pxa2xx_mainstone.c index 92016fe932b4..1138551ba8f6 100644 --- a/trunk/drivers/pcmcia/pxa2xx_mainstone.c +++ b/trunk/drivers/pcmcia/pxa2xx_mainstone.c @@ -44,7 +44,7 @@ static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) * before we enable them as outputs. */ - skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ; + skt->irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ; return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); } diff --git a/trunk/drivers/pcmcia/pxa2xx_palmld.c b/trunk/drivers/pcmcia/pxa2xx_palmld.c index 6fb6f7f0672e..5ba9b3664a00 100644 --- a/trunk/drivers/pcmcia/pxa2xx_palmld.c +++ b/trunk/drivers/pcmcia/pxa2xx_palmld.c @@ -45,7 +45,7 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) if (ret) goto err4; - skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); + skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); return 0; err4: diff --git a/trunk/drivers/pcmcia/pxa2xx_palmtx.c b/trunk/drivers/pcmcia/pxa2xx_palmtx.c index b07b247a399f..e07b5c51ec5b 100644 --- a/trunk/drivers/pcmcia/pxa2xx_palmtx.c +++ b/trunk/drivers/pcmcia/pxa2xx_palmtx.c @@ -53,7 +53,7 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) if (ret) goto err5; - skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); + skt->irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); return 0; err5: diff --git a/trunk/drivers/pcmcia/pxa2xx_sharpsl.c b/trunk/drivers/pcmcia/pxa2xx_sharpsl.c index 0ea3b29440e6..bc43f78f6f0b 100644 --- a/trunk/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/trunk/drivers/pcmcia/pxa2xx_sharpsl.c @@ -66,7 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) } } - skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; + skt->irq = SCOOP_DEV[skt->nr].irq; return 0; } diff --git a/trunk/drivers/pcmcia/pxa2xx_trizeps4.c b/trunk/drivers/pcmcia/pxa2xx_trizeps4.c index b7e596620db1..e0e5cb339b4a 100644 --- a/trunk/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/trunk/drivers/pcmcia/pxa2xx_trizeps4.c @@ -53,7 +53,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) gpio_free(GPIO_PRDY); return -EINVAL; } - skt->socket.pci_irq = IRQ_GPIO(GPIO_PRDY); + skt->irq = IRQ_GPIO(GPIO_PRDY); break; #ifndef CONFIG_MACH_TRIZEPS_CONXS @@ -63,7 +63,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) break; } /* release the reset of this card */ - pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq); + pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq); /* supplementory irqs for the socket */ for (i = 0; i < ARRAY_SIZE(irqs); i++) { diff --git a/trunk/drivers/pcmcia/pxa2xx_viper.c b/trunk/drivers/pcmcia/pxa2xx_viper.c index 27be2e154df2..17871360fe99 100644 --- a/trunk/drivers/pcmcia/pxa2xx_viper.c +++ b/trunk/drivers/pcmcia/pxa2xx_viper.c @@ -40,7 +40,7 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { unsigned long flags; - skt->socket.pci_irq = gpio_to_irq(VIPER_CF_RDY_GPIO); + skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO); if (gpio_request(VIPER_CF_CD_GPIO, "CF detect")) goto err_request_cd; diff --git a/trunk/drivers/pcmcia/rsrc_mgr.c b/trunk/drivers/pcmcia/rsrc_mgr.c index de0e770ce6a3..e592e0e0d7ed 100644 --- a/trunk/drivers/pcmcia/rsrc_mgr.c +++ b/trunk/drivers/pcmcia/rsrc_mgr.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "cs_internal.h" diff --git a/trunk/drivers/pcmcia/sa1100_assabet.c b/trunk/drivers/pcmcia/sa1100_assabet.c index fd013a1ef47a..ac8aa09ba0da 100644 --- a/trunk/drivers/pcmcia/sa1100_assabet.c +++ b/trunk/drivers/pcmcia/sa1100_assabet.c @@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = { static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; + skt->irq = ASSABET_IRQ_GPIO_CF_IRQ; return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); } diff --git a/trunk/drivers/pcmcia/sa1100_badge4.c b/trunk/drivers/pcmcia/sa1100_badge4.c index 1ce53f493bef..1ca9737ea79e 100644 --- a/trunk/drivers/pcmcia/sa1100_badge4.c +++ b/trunk/drivers/pcmcia/sa1100_badge4.c @@ -127,10 +127,13 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state static struct pcmcia_low_level badge4_pcmcia_ops = { .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, + .socket_init = sa1111_pcmcia_socket_init, - .first = 0, - .nr = 2, + .socket_suspend = sa1111_pcmcia_socket_suspend, }; int pcmcia_badge4_init(struct device *dev) @@ -143,9 +146,7 @@ int pcmcia_badge4_init(struct device *dev) __func__, badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); - sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); - ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, - sa11xx_drv_pcmcia_add_one); + ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2); } return ret; diff --git a/trunk/drivers/pcmcia/sa1100_cerf.c b/trunk/drivers/pcmcia/sa1100_cerf.c index 9bf088b17275..63e6bc431a0d 100644 --- a/trunk/drivers/pcmcia/sa1100_cerf.c +++ b/trunk/drivers/pcmcia/sa1100_cerf.c @@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = { static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; + skt->irq = CERF_IRQ_GPIO_CF_IRQ; return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); } diff --git a/trunk/drivers/pcmcia/sa1100_generic.c b/trunk/drivers/pcmcia/sa1100_generic.c index 11cc3ba1260a..2d0e99751530 100644 --- a/trunk/drivers/pcmcia/sa1100_generic.c +++ b/trunk/drivers/pcmcia/sa1100_generic.c @@ -83,16 +83,7 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) static int sa11x0_drv_pcmcia_remove(struct platform_device *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; + return soc_common_drv_pcmcia_remove(&dev->dev); } static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev, diff --git a/trunk/drivers/pcmcia/sa1100_h3600.c b/trunk/drivers/pcmcia/sa1100_h3600.c index 3a121ac697d6..0cc3748f3758 100644 --- a/trunk/drivers/pcmcia/sa1100_h3600.c +++ b/trunk/drivers/pcmcia/sa1100_h3600.c @@ -25,8 +25,8 @@ static struct pcmcia_irqs irqs[] = { static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - skt->socket.pci_irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1 - : IRQ_GPIO_H3600_PCMCIA_IRQ0; + skt->irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1 + : IRQ_GPIO_H3600_PCMCIA_IRQ0; return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); diff --git a/trunk/drivers/pcmcia/sa1100_jornada720.c b/trunk/drivers/pcmcia/sa1100_jornada720.c index 6bcabee6bde4..7eedb42f800c 100644 --- a/trunk/drivers/pcmcia/sa1100_jornada720.c +++ b/trunk/drivers/pcmcia/sa1100_jornada720.c @@ -22,10 +22,25 @@ #define SOCKET1_POWER (GPIO_GPIO1 | 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 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; int ret; @@ -82,7 +97,7 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s unsigned long flags; local_irq_save(flags); - sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); + sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); local_irq_restore(flags); } @@ -91,30 +106,21 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s static struct pcmcia_low_level jornada720_pcmcia_ops = { .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, + .socket_init = sa1111_pcmcia_socket_init, - .first = 0, - .nr = 2, + .socket_suspend = sa1111_pcmcia_socket_suspend, }; int __devinit pcmcia_jornada720_init(struct device *dev) { int ret = -ENODEV; - if (machine_is_jornada720()) { - 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); - } + if (machine_is_jornada720()) + ret = sa11xx_drv_pcmcia_probe(dev, &jornada720_pcmcia_ops, 0, 2); return ret; } diff --git a/trunk/drivers/pcmcia/sa1100_neponset.c b/trunk/drivers/pcmcia/sa1100_neponset.c index c95639b5f2a0..0c76d337815b 100644 --- a/trunk/drivers/pcmcia/sa1100_neponset.c +++ b/trunk/drivers/pcmcia/sa1100_neponset.c @@ -43,7 +43,6 @@ static int 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; int ret; @@ -100,7 +99,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set; local_irq_restore(flags); - sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); + sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); } return 0; @@ -116,10 +115,12 @@ static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt) static struct pcmcia_low_level neponset_pcmcia_ops = { .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, .socket_init = neponset_pcmcia_socket_init, - .first = 0, - .nr = 2, + .socket_suspend = sa1111_pcmcia_socket_suspend, }; int pcmcia_neponset_init(struct sa1111_dev *sadev) @@ -134,9 +135,7 @@ 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(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); - sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); - ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, - sa11xx_drv_pcmcia_add_one); + ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2); } return ret; diff --git a/trunk/drivers/pcmcia/sa1100_shannon.c b/trunk/drivers/pcmcia/sa1100_shannon.c index c4d51867a050..46d8c1977c2a 100644 --- a/trunk/drivers/pcmcia/sa1100_shannon.c +++ b/trunk/drivers/pcmcia/sa1100_shannon.c @@ -28,7 +28,7 @@ static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); - skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; + skt->irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); } diff --git a/trunk/drivers/pcmcia/sa1100_simpad.c b/trunk/drivers/pcmcia/sa1100_simpad.c index 05bd504e6f18..33a08ae09fdf 100644 --- a/trunk/drivers/pcmcia/sa1100_simpad.c +++ b/trunk/drivers/pcmcia/sa1100_simpad.c @@ -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); - skt->socket.pci_irq = IRQ_GPIO_CF_IRQ; + skt->irq = IRQ_GPIO_CF_IRQ; return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); } diff --git a/trunk/drivers/pcmcia/sa1111_generic.c b/trunk/drivers/pcmcia/sa1111_generic.c index de6bc333d299..4be4e172ffa1 100644 --- a/trunk/drivers/pcmcia/sa1111_generic.c +++ b/trunk/drivers/pcmcia/sa1111_generic.c @@ -28,20 +28,23 @@ static struct pcmcia_irqs irqs[] = { { 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" }, }; -static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +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)); } -static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); } void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - struct sa1111_pcmcia_socket *s = to_skt(skt); - unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR); + struct sa1111_dev *sadev = SA1111_DEV(skt->dev); + unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR); switch (skt->nr) { case 0: @@ -68,7 +71,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) { - struct sa1111_pcmcia_socket *s = to_skt(skt); + struct sa1111_dev *sadev = SA1111_DEV(skt->dev); unsigned int pccr_skt_mask, pccr_set_mask, val; unsigned long flags; @@ -97,10 +100,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; local_irq_save(flags); - val = sa1111_readl(s->dev->mapbase + SA1111_PCCR); + val = sa1111_readl(sadev->mapbase + SA1111_PCCR); val &= ~pccr_skt_mask; val |= pccr_set_mask & pccr_skt_mask; - sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); + sa1111_writel(val, sadev->mapbase + SA1111_PCCR); local_irq_restore(flags); return 0; @@ -111,51 +114,15 @@ void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt) soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); } -static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) +void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { 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) { void __iomem *base; - dev_set_drvdata(&dev->dev, NULL); - if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) return -EBUSY; @@ -185,15 +152,7 @@ static int pcmcia_probe(struct sa1111_dev *dev) static int __devexit pcmcia_remove(struct sa1111_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); - } - + soc_common_drv_pcmcia_remove(&dev->dev); release_mem_region(dev->res.start, 512); return 0; } diff --git a/trunk/drivers/pcmcia/sa1111_generic.h b/trunk/drivers/pcmcia/sa1111_generic.h index 02dc8577cdaf..10ced4a210d7 100644 --- a/trunk/drivers/pcmcia/sa1111_generic.h +++ b/trunk/drivers/pcmcia/sa1111_generic.h @@ -1,23 +1,12 @@ #include "soc_common.h" #include "sa11xx_base.h" -struct sa1111_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 int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *); +extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *); 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 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_jornada720_init(struct device *); diff --git a/trunk/drivers/pcmcia/sa11xx_base.c b/trunk/drivers/pcmcia/sa11xx_base.c index fc9a6527019b..e15d59f2d8a9 100644 --- a/trunk/drivers/pcmcia/sa11xx_base.c +++ b/trunk/drivers/pcmcia/sa11xx_base.c @@ -171,58 +171,12 @@ static const char *skt_names[] = { #define SKT_DEV_INFO_SIZE(n) \ (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) -int sa11xx_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); -} -EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one); - -void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops) -{ - /* - * set default MECR calculation if the board specific - * code did not specify one... - */ - if (!ops->get_timing) - ops->get_timing = sa1100_pcmcia_default_mecr_timing; - - /* Provide our SA11x0 specific timing routines. */ - ops->set_timing = sa1100_pcmcia_set_timing; - ops->show_timing = sa1100_pcmcia_show_timing; -#ifdef CONFIG_CPU_FREQ - ops->frequency_change = sa1100_pcmcia_frequency_change; -#endif -} -EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops); - 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); + int i; sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); if (!sinfo) @@ -234,26 +188,45 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, 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; + skt->nr = first + i; + skt->irq = NO_IRQ; - ret = sa11xx_drv_pcmcia_add_one(skt); - if (ret) - break; - } + 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; - if (ret) { - while (--i >= 0) - soc_pcmcia_remove_one(&sinfo->skt[i]); - kfree(sinfo); - } else { - dev_set_drvdata(dev, sinfo); + 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 ret; + /* + * set default MECR calculation if the board specific + * code did not specify one... + */ + if (!ops->get_timing) + ops->get_timing = sa1100_pcmcia_default_mecr_timing; + + /* Provide our SA11x0 specific timing routines. */ + ops->set_timing = sa1100_pcmcia_set_timing; + ops->show_timing = sa1100_pcmcia_show_timing; +#ifdef CONFIG_CPU_FREQ + ops->frequency_change = sa1100_pcmcia_frequency_change; +#endif + + return soc_common_drv_pcmcia_probe(dev, ops, sinfo); } EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe); diff --git a/trunk/drivers/pcmcia/sa11xx_base.h b/trunk/drivers/pcmcia/sa11xx_base.h index 3d76d720f463..7bc208280527 100644 --- a/trunk/drivers/pcmcia/sa11xx_base.h +++ b/trunk/drivers/pcmcia/sa11xx_base.h @@ -118,8 +118,6 @@ 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); #endif /* !defined(_PCMCIA_SA1100_H) */ diff --git a/trunk/drivers/pcmcia/soc_common.c b/trunk/drivers/pcmcia/soc_common.c index 6f1a86b43c60..ef7e9e58782b 100644 --- a/trunk/drivers/pcmcia/soc_common.c +++ b/trunk/drivers/pcmcia/soc_common.c @@ -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) { skt->irq_state = 1; - set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING); + set_irq_type(skt->irq, IRQ_TYPE_EDGE_FALLING); } else if (skt->irq_state == 1 && state->io_irq == 0) { skt->irq_state = 0; - set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE); + set_irq_type(skt->irq, IRQ_TYPE_NONE); } skt->cs_state = *state; @@ -492,8 +492,7 @@ 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, "Vpp : %d\n", skt->cs_state.Vpp); - p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, - skt->socket.pci_irq); + p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, skt->irq); if (skt->ops->show_timing) p+=skt->ops->show_timing(skt, p); @@ -575,7 +574,7 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, EXPORT_SYMBOL(soc_pcmcia_enable_irqs); -static LIST_HEAD(soc_pcmcia_sockets); +LIST_HEAD(soc_pcmcia_sockets); static DEFINE_MUTEX(soc_pcmcia_sockets_lock); #ifdef CONFIG_CPU_FREQ @@ -610,137 +609,177 @@ static int soc_pcmcia_cpufreq_register(void) "notifier for PCMCIA (%d)\n", ret); return ret; } -fs_initcall(soc_pcmcia_cpufreq_register); static void soc_pcmcia_cpufreq_unregister(void) { 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 -void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) +int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, + struct skt_dev_info *sinfo) { - mutex_lock(&soc_pcmcia_sockets_lock); - del_timer_sync(&skt->poll_timer); - - pcmcia_unregister_socket(&skt->socket); + struct soc_pcmcia_socket *skt; + int ret, i; - flush_scheduled_work(); + mutex_lock(&soc_pcmcia_sockets_lock); - skt->ops->hw_shutdown(skt); + /* + * Initialise the per-socket structure. + */ + for (i = 0; i < sinfo->nskt; i++) { + skt = &sinfo->skt[i]; - soc_common_pcmcia_config_skt(skt, &dead_socket); + skt->socket.ops = &soc_common_pcmcia_operations; + skt->socket.owner = ops->owner; + skt->socket.dev.parent = dev; - list_del(&skt->node); - mutex_unlock(&soc_pcmcia_sockets_lock); + 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; - 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); + skt->dev = dev; + skt->ops = ops; -int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) -{ - int ret; + ret = request_resource(&iomem_resource, &skt->res_skt); + if (ret) + goto out_err_1; - 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(&skt->res_skt, &skt->res_io); + if (ret) + goto out_err_2; - ret = request_resource(&iomem_resource, &skt->res_skt); - if (ret) - goto out_err_1; + ret = request_resource(&skt->res_skt, &skt->res_mem); + if (ret) + goto out_err_3; - ret = request_resource(&skt->res_skt, &skt->res_io); - if (ret) - goto out_err_2; + ret = request_resource(&skt->res_skt, &skt->res_attr); + if (ret) + goto out_err_4; - ret = request_resource(&skt->res_skt, &skt->res_mem); - if (ret) - goto out_err_3; + skt->virt_io = ioremap(skt->res_io.start, 0x10000); + if (skt->virt_io == NULL) { + ret = -ENOMEM; + goto out_err_5; + } - ret = request_resource(&skt->res_skt, &skt->res_attr); - if (ret) - goto out_err_4; + if (list_empty(&soc_pcmcia_sockets)) + soc_pcmcia_cpufreq_register(); - skt->virt_io = ioremap(skt->res_io.start, 0x10000); - if (skt->virt_io == NULL) { - ret = -ENOMEM; - goto out_err_5; - } + list_add(&skt->node, &soc_pcmcia_sockets); - mutex_lock(&soc_pcmcia_sockets_lock); + /* + * We initialize default socket timing here, because + * we are not guaranteed to see a SetIOMap operation at + * runtime. + */ + ops->set_timing(skt); - list_add(&skt->node, &soc_pcmcia_sockets); + ret = ops->hw_init(skt); + if (ret) + goto out_err_6; - /* - * We initialize default socket timing here, because - * we are not guaranteed to see a SetIOMap operation at - * runtime. - */ - skt->ops->set_timing(skt); + 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; - ret = skt->ops->hw_init(skt); - if (ret) - goto out_err_6; + skt->status = soc_common_pcmcia_skt_state(skt); - skt->socket.ops = &soc_common_pcmcia_operations; - 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.io_offset = (unsigned long)skt->virt_io; + ret = pcmcia_register_socket(&skt->socket); + if (ret) + goto out_err_7; - 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); + add_timer(&skt->poll_timer); - mutex_unlock(&soc_pcmcia_sockets_lock); + ret = device_create_file(&skt->socket.dev, &dev_attr_status); + if (ret) + goto out_err_8; + } - 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; - return ret; + do { + skt = &sinfo->skt[i]; + device_remove_file(&skt->socket.dev, &dev_attr_status); out_err_8: - mutex_lock(&soc_pcmcia_sockets_lock); - del_timer_sync(&skt->poll_timer); - pcmcia_unregister_socket(&skt->socket); + del_timer_sync(&skt->poll_timer); + pcmcia_unregister_socket(&skt->socket); out_err_7: - flush_scheduled_work(); + flush_scheduled_work(); - skt->ops->hw_shutdown(skt); + ops->hw_shutdown(skt); out_err_6: - list_del(&skt->node); - mutex_unlock(&soc_pcmcia_sockets_lock); - iounmap(skt->virt_io); + list_del(&skt->node); + iounmap(skt->virt_io); out_err_5: - release_resource(&skt->res_attr); + release_resource(&skt->res_attr); out_err_4: - release_resource(&skt->res_mem); + release_resource(&skt->res_mem); out_err_3: - release_resource(&skt->res_io); + release_resource(&skt->res_io); out_err_2: - release_resource(&skt->res_skt); + release_resource(&skt->res_skt); out_err_1: + i--; + } while (i > 0); + kfree(sinfo); + + out: + mutex_unlock(&soc_pcmcia_sockets_lock); return ret; } -EXPORT_SYMBOL(soc_pcmcia_add_one); -MODULE_AUTHOR("John Dorsey "); -MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support"); -MODULE_LICENSE("Dual MPL/GPL"); +int soc_common_drv_pcmcia_remove(struct device *dev) +{ + struct skt_dev_info *sinfo = dev_get_drvdata(dev); + 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); diff --git a/trunk/drivers/pcmcia/soc_common.h b/trunk/drivers/pcmcia/soc_common.h index e40824ce6b0b..290e143839ee 100644 --- a/trunk/drivers/pcmcia/soc_common.h +++ b/trunk/drivers/pcmcia/soc_common.h @@ -30,12 +30,14 @@ struct soc_pcmcia_socket { /* * Info from low level handler */ + struct device *dev; unsigned int nr; + unsigned int irq; /* * Core PCMCIA state */ - const struct pcmcia_low_level *ops; + struct pcmcia_low_level *ops; unsigned int status; socket_state_t cs_state; @@ -133,8 +135,10 @@ 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 *); -void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); -int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); +extern struct list_head soc_pcmcia_sockets; + +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 diff --git a/trunk/drivers/pcmcia/tcic.c b/trunk/drivers/pcmcia/tcic.c index 12c49ee135e1..6918849d511e 100644 --- a/trunk/drivers/pcmcia/tcic.c +++ b/trunk/drivers/pcmcia/tcic.c @@ -55,6 +55,21 @@ #include #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 "); MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver"); MODULE_LICENSE("Dual MPL/GPL"); @@ -559,7 +574,7 @@ static irqreturn_t tcic_interrupt(int irq, void *dev) } else active = 1; - pr_debug("tcic_interrupt()\n"); + debug(2, "tcic_interrupt()\n"); for (i = 0; i < sockets; i++) { psock = socket_table[i].psock; @@ -596,13 +611,13 @@ static irqreturn_t tcic_interrupt(int irq, void *dev) } active = 0; - pr_debug("interrupt done\n"); + debug(2, "interrupt done\n"); return IRQ_HANDLED; } /* tcic_interrupt */ static void tcic_timer(u_long data) { - pr_debug("tcic_timer()\n"); + debug(2, "tcic_timer()\n"); tcic_timer_pending = 0; tcic_interrupt(0, NULL); } /* tcic_timer */ @@ -629,7 +644,7 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value) reg = tcic_getb(TCIC_PWR); if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock))) *value |= SS_POWERON; - dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value); + debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value); return 0; } /* tcic_get_status */ @@ -641,7 +656,7 @@ static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state) u_char reg; u_short scf1, scf2; - dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " + debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG); @@ -716,7 +731,7 @@ static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) u_int addr; u_short base, len, ioctl; - dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, " + debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, " "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed, (unsigned long long)io->start, (unsigned long long)io->stop); if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) || @@ -753,7 +768,7 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m u_short addr, ctl; u_long base, len, mmap; - dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, " + debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, " "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags, mem->speed, (unsigned long long)mem->res->start, (unsigned long long)mem->res->end, mem->card_start); diff --git a/trunk/drivers/pcmcia/topic.h b/trunk/drivers/pcmcia/topic.h index 615a45a8fe86..edccfa5bb400 100644 --- a/trunk/drivers/pcmcia/topic.h +++ b/trunk/drivers/pcmcia/topic.h @@ -114,17 +114,22 @@ static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff) reg_zv |= TOPIC97_ZV_CONTROL_ENABLE; 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 |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL; config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg); - } else { +#endif + } + else { reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE; 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) diff --git a/trunk/drivers/scsi/pcmcia/aha152x_stub.c b/trunk/drivers/scsi/pcmcia/aha152x_stub.c index 528733b4a392..67cde0138061 100644 --- a/trunk/drivers/scsi/pcmcia/aha152x_stub.c +++ b/trunk/drivers/scsi/pcmcia/aha152x_stub.c @@ -54,6 +54,15 @@ #include #include +#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 /*====================================================================*/ @@ -94,7 +103,7 @@ static int aha152x_probe(struct pcmcia_device *link) { scsi_info_t *info; - dev_dbg(&link->dev, "aha152x_attach()\n"); + DEBUG(0, "aha152x_attach()\n"); /* Create new SCSI device */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -106,6 +115,7 @@ static int aha152x_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -117,7 +127,7 @@ static int aha152x_probe(struct pcmcia_device *link) static void aha152x_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "aha152x_detach\n"); + DEBUG(0, "aha152x_detach(0x%p)\n", link); aha152x_release_cs(link); @@ -127,6 +137,9 @@ 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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -151,22 +164,19 @@ static int aha152x_config_cs(struct pcmcia_device *link) { scsi_info_t *info = link->priv; struct aha152x_setup s; - int ret; + int last_ret, last_fn; struct Scsi_Host *host; - dev_dbg(&link->dev, "aha152x_config\n"); - - ret = pcmcia_loop_config(link, aha152x_config_check, NULL); - if (ret) - goto failed; + DEBUG(0, "aha152x_config(0x%p)\n", link); - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_ret); + goto failed; + } - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* Set configuration options for the aha152x driver */ memset(&s, 0, sizeof(s)); @@ -184,7 +194,7 @@ static int aha152x_config_cs(struct pcmcia_device *link) host = aha152x_probe_one(&s); if (host == NULL) { printk(KERN_INFO "aha152x_cs: no SCSI devices found\n"); - goto failed; + goto cs_failed; } sprintf(info->node.dev_name, "scsi%d", host->host_no); @@ -193,6 +203,8 @@ static int aha152x_config_cs(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: aha152x_release_cs(link); return -ENODEV; diff --git a/trunk/drivers/scsi/pcmcia/fdomain_stub.c b/trunk/drivers/scsi/pcmcia/fdomain_stub.c index 914040684079..06254f46a0dd 100644 --- a/trunk/drivers/scsi/pcmcia/fdomain_stub.c +++ b/trunk/drivers/scsi/pcmcia/fdomain_stub.c @@ -59,6 +59,16 @@ MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver"); 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 { @@ -76,7 +86,7 @@ static int fdomain_probe(struct pcmcia_device *link) { scsi_info_t *info; - dev_dbg(&link->dev, "fdomain_attach()\n"); + DEBUG(0, "fdomain_attach()\n"); /* Create new SCSI device */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -89,6 +99,7 @@ static int fdomain_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -100,7 +111,7 @@ static int fdomain_probe(struct pcmcia_device *link) static void fdomain_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "fdomain_detach\n"); + DEBUG(0, "fdomain_detach(0x%p)\n", link); fdomain_release(link); @@ -109,6 +120,9 @@ 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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -123,22 +137,20 @@ static int fdomain_config_check(struct pcmcia_device *p_dev, static int fdomain_config(struct pcmcia_device *link) { scsi_info_t *info = link->priv; - int ret; + int last_ret, last_fn; char str[22]; struct Scsi_Host *host; - dev_dbg(&link->dev, "fdomain_config\n"); + DEBUG(0, "fdomain_config(0x%p)\n", link); - ret = pcmcia_loop_config(link, fdomain_config_check, NULL); - if (ret) + last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_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(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* A bad hack... */ release_region(link->io.BasePort1, link->io.NumPorts1); @@ -150,11 +162,11 @@ static int fdomain_config(struct pcmcia_device *link) host = __fdomain_16x0_detect(&fdomain_driver_template); if (!host) { printk(KERN_INFO "fdomain_cs: no SCSI devices found\n"); - goto failed; + goto cs_failed; } if (scsi_add_host(host, NULL)) - goto failed; + goto cs_failed; scsi_scan_host(host); sprintf(info->node.dev_name, "scsi%d", host->host_no); @@ -163,6 +175,8 @@ static int fdomain_config(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: fdomain_release(link); return -ENODEV; @@ -174,7 +188,7 @@ static void fdomain_release(struct pcmcia_device *link) { scsi_info_t *info = link->priv; - dev_dbg(&link->dev, "fdomain_release\n"); + DEBUG(0, "fdomain_release(0x%p)\n", link); scsi_remove_host(info->host); pcmcia_disable_device(link); diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.c b/trunk/drivers/scsi/pcmcia/nsp_cs.c index c2341af587a3..e32c344d7ad8 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.c +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.c @@ -1564,10 +1564,12 @@ static int nsp_cs_probe(struct pcmcia_device *link) link->io.IOAddrLines = 10; /* not used */ /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; /* Interrupt handler */ link->irq.Handler = &nspintr; + link->irq.Instance = info; link->irq.Attributes |= IRQF_SHARED; /* General socket configuration */ @@ -1682,10 +1684,10 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev, if (cfg_mem->req.Size < 0x1000) cfg_mem->req.Size = 0x1000; 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; map.Page = 0; map.CardOffset = mem->win[0].card_addr; - if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0) + if (pcmcia_map_mem_page(p_dev->win, &map) != 0) goto next_entry; cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size); diff --git a/trunk/drivers/scsi/pcmcia/qlogic_stub.c b/trunk/drivers/scsi/pcmcia/qlogic_stub.c index f85f094870b4..20c3e5e6d88a 100644 --- a/trunk/drivers/scsi/pcmcia/qlogic_stub.c +++ b/trunk/drivers/scsi/pcmcia/qlogic_stub.c @@ -62,6 +62,15 @@ 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 = { .module = THIS_MODULE, .name = qlogic_name, @@ -150,7 +159,7 @@ static int qlogic_probe(struct pcmcia_device *link) { scsi_info_t *info; - dev_dbg(&link->dev, "qlogic_attach()\n"); + DEBUG(0, "qlogic_attach()\n"); /* Create new SCSI device */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -162,6 +171,7 @@ static int qlogic_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Present = PRESENT_OPTION; @@ -173,7 +183,7 @@ static int qlogic_probe(struct pcmcia_device *link) static void qlogic_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "qlogic_detach\n"); + DEBUG(0, "qlogic_detach(0x%p)\n", link); qlogic_release(link); kfree(link->priv); @@ -182,6 +192,9 @@ 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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -200,22 +213,19 @@ static int qlogic_config_check(struct pcmcia_device *p_dev, static int qlogic_config(struct pcmcia_device * link) { scsi_info_t *info = link->priv; - int ret; + int last_ret, last_fn; struct Scsi_Host *host; - dev_dbg(&link->dev, "qlogic_config\n"); + DEBUG(0, "qlogic_config(0x%p)\n", link); - ret = pcmcia_loop_config(link, qlogic_config_check, NULL); - if (ret) - goto failed; - - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_ret); goto failed; + } - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { /* set ATAcmd */ @@ -234,7 +244,7 @@ static int qlogic_config(struct pcmcia_device * link) if (!host) { printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); - goto failed; + goto cs_failed; } sprintf(info->node.dev_name, "scsi%d", host->host_no); @@ -243,9 +253,12 @@ static int qlogic_config(struct pcmcia_device * link) return 0; -failed: +cs_failed: + cs_error(link, last_fn, last_ret); pcmcia_disable_device(link); +failed: return -ENODEV; + } /* qlogic_config */ /*====================================================================*/ @@ -254,7 +267,7 @@ static void qlogic_release(struct pcmcia_device *link) { scsi_info_t *info = link->priv; - dev_dbg(&link->dev, "qlogic_release\n"); + DEBUG(0, "qlogic_release(0x%p)\n", link); scsi_remove_host(info->host); diff --git a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c index e7564d8f0cbf..b330c11a1752 100644 --- a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c @@ -77,6 +77,17 @@ #include #include +/* ================================================================== */ + +#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 /* ================================================================== */ @@ -514,7 +525,7 @@ SYM53C500_release(struct pcmcia_device *link) struct scsi_info_t *info = link->priv; struct Scsi_Host *shost = info->host; - dev_dbg(&link->dev, "SYM53C500_release\n"); + DEBUG(0, "SYM53C500_release(0x%p)\n", link); /* * Do this before releasing/freeing resources. @@ -686,6 +697,9 @@ static struct scsi_host_template sym53c500_driver_template = { .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, cistpl_cftable_entry_t *cfg, cistpl_cftable_entry_t *dflt, @@ -705,27 +719,24 @@ static int SYM53C500_config(struct pcmcia_device *link) { struct scsi_info_t *info = link->priv; - int ret; + int last_ret, last_fn; int irq_level, port_base; struct Scsi_Host *host; struct scsi_host_template *tpnt = &sym53c500_driver_template; struct sym53c500_data *data; - dev_dbg(&link->dev, "SYM53C500_config\n"); + DEBUG(0, "SYM53C500_config(0x%p)\n", link); info->manf_id = link->manf_id; - ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL); - if (ret) - goto failed; - - ret = pcmcia_request_irq(link, &link->irq); - if (ret) + last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL); + if (last_ret) { + cs_error(link, RequestIO, last_ret); goto failed; + } - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); /* * That's the trouble with copying liberally from another driver. @@ -813,6 +824,8 @@ SYM53C500_config(struct pcmcia_device *link) printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n"); return -ENODEV; +cs_failed: + cs_error(link, last_fn, last_ret); failed: SYM53C500_release(link); return -ENODEV; @@ -842,7 +855,7 @@ static int sym53c500_resume(struct pcmcia_device *link) static void SYM53C500_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "SYM53C500_detach\n"); + DEBUG(0, "SYM53C500_detach(0x%p)\n", link); SYM53C500_release(link); @@ -855,7 +868,7 @@ SYM53C500_probe(struct pcmcia_device *link) { struct scsi_info_t *info; - dev_dbg(&link->dev, "SYM53C500_attach()\n"); + DEBUG(0, "SYM53C500_attach()\n"); /* Create new SCSI device */ info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -867,6 +880,7 @@ SYM53C500_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; diff --git a/trunk/drivers/serial/serial_cs.c b/trunk/drivers/serial/serial_cs.c index fc413f0f8dd2..7c7914f5fa02 100644 --- a/trunk/drivers/serial/serial_cs.c +++ b/trunk/drivers/serial/serial_cs.c @@ -54,6 +54,14 @@ #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 /*====================================================================*/ @@ -113,20 +121,24 @@ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_ static int quirk_post_ibm(struct pcmcia_device *link) { conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; - int ret; - - ret = pcmcia_access_configuration_register(link, ®); - if (ret) - goto failed; + int last_ret, last_fn; + last_ret = pcmcia_access_configuration_register(link, ®); + if (last_ret) { + last_fn = AccessConfigurationRegister; + goto cs_failed; + } reg.Action = CS_WRITE; reg.Value = reg.Value | 1; - 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; + } return 0; - failed: + cs_failed: + cs_error(link, last_fn, last_ret); return -ENODEV; } @@ -271,7 +283,7 @@ static void serial_remove(struct pcmcia_device *link) struct serial_info *info = link->priv; int i; - dev_dbg(&link->dev, "serial_release\n"); + DEBUG(0, "serial_release(0x%p)\n", link); /* * Recheck to see if the device is still configured. @@ -322,7 +334,7 @@ static int serial_probe(struct pcmcia_device *link) { struct serial_info *info; - dev_dbg(&link->dev, "serial_attach()\n"); + DEBUG(0, "serial_attach()\n"); /* Create new serial device */ info = kzalloc(sizeof (*info), GFP_KERNEL); @@ -334,6 +346,7 @@ static int serial_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; if (do_sound) { link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -357,7 +370,7 @@ static void serial_detach(struct pcmcia_device *link) { struct serial_info *info = link->priv; - dev_dbg(&link->dev, "serial_detach\n"); + DEBUG(0, "serial_detach(0x%p)\n", link); /* * Ensure any outstanding scheduled tasks are completed. @@ -386,7 +399,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, port.irq = irq; port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; port.uartclk = 1843200; - port.dev = &handle->dev; + port.dev = &handle_to_dev(handle); if (buggy_uart) port.flags |= UPF_BUGGY_UART; @@ -413,6 +426,21 @@ 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, cistpl_cftable_entry_t *cf, cistpl_cftable_entry_t *dflt, @@ -494,13 +522,15 @@ static int simple_config(struct pcmcia_device *link) printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); + cs_error(link, RequestIO, i); return -1; found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != 0) + if (i != 0) { + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; - + } if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); @@ -511,8 +541,10 @@ static int simple_config(struct pcmcia_device *link) info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if (i != 0) { + cs_error(link, RequestConfiguration, i); return -1; + } return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); } @@ -581,6 +613,7 @@ static int multi_config(struct pcmcia_device *link) /* FIXME: comment does not fit, error handling does not fit */ printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); + cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } @@ -591,8 +624,10 @@ static int multi_config(struct pcmcia_device *link) info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) + if (i != 0) { + cs_error(link, RequestConfiguration, i); return -ENODEV; + } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: * 8 registers are for the UART, the others are extra registers. @@ -630,25 +665,6 @@ static int multi_config(struct pcmcia_device *link) 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 @@ -660,14 +676,46 @@ static int serial_check_for_multi(struct pcmcia_device *p_dev, static int serial_config(struct pcmcia_device * link) { struct serial_info *info = link->priv; - int i; + struct serial_cfg_mem *cfg_mem; + tuple_t *tuple; + u_char *buf; + cisparse_t *parse; + cistpl_cftable_entry_t *cf; + int i, last_ret, last_fn; - dev_dbg(&link->dev, "serial_config\n"); + DEBUG(0, "serial_config(0x%p)\n", link); + + 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? */ - info->multi = (link->socket->functions > 1); + tuple->DesiredTuple = CISTPL_LONGLINK_MFC; + tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; + info->multi = (first_tuple(link, tuple, parse) == 0); /* Is this a multiport card? */ + tuple->DesiredTuple = CISTPL_MANFID; info->manfid = link->manf_id; info->prodid = link->card_id; @@ -682,11 +730,20 @@ static int serial_config(struct pcmcia_device * link) /* Another check for dual-serial cards: look for either serial or multifunction cards that ask for appropriate IO port ranges */ + tuple->DesiredTuple = CISTPL_FUNCID; if ((info->multi == 0) && (link->has_func_id) && ((link->func_id == CISTPL_FUNCID_MULTI) || - (link->func_id == CISTPL_FUNCID_SERIAL))) - pcmcia_loop_config(link, serial_check_for_multi, info); + (link->func_id == CISTPL_FUNCID_SERIAL))) { + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; + 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. @@ -711,10 +768,14 @@ static int serial_config(struct pcmcia_device * link) goto failed; link->dev_node = &info->node[0]; + kfree(cfg_mem); return 0; +cs_failed: + cs_error(link, last_fn, last_ret); failed: serial_remove(link); + kfree(cfg_mem); return -ENODEV; } diff --git a/trunk/drivers/ssb/pcmcia.c b/trunk/drivers/ssb/pcmcia.c index e72f4046a5e0..100e7a5c5ea1 100644 --- a/trunk/drivers/ssb/pcmcia.c +++ b/trunk/drivers/ssb/pcmcia.c @@ -617,117 +617,15 @@ static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size) } \ } while (0) -static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev, - tuple_t *tuple, - void *priv) -{ - struct ssb_sprom *sprom = priv; - - 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_boardinfo *bi = &iv->boardinfo; - 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; + tuple_t tuple; int res; + unsigned char buf[32]; + struct ssb_sprom *sprom = &iv->sprom; + struct ssb_boardinfo *bi = &iv->boardinfo; + const char *error_description; memset(sprom, 0xFF, sizeof(*sprom)); sprom->revision = 1; @@ -735,22 +633,120 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, sprom->boardflags_hi = 0; /* First fetch the MAC address. */ - res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE, - ssb_pcmcia_get_mac, sprom); - if (res != 0) { - ssb_printk(KERN_ERR PFX - "PCMCIA: Failed to fetch MAC address\n"); - return -ENODEV; + memset(&tuple, 0, sizeof(tuple)); + tuple.DesiredTuple = CISTPL_FUNCE; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple); + GOTO_ERROR_ON(res != 0, "MAC first tpl"); + 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. */ - res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS, - ssb_pcmcia_do_get_invariants, sprom); - if ((res == 0) || (res == -ENOSPC)) - return 0; + memset(&tuple, 0, sizeof(tuple)); + tuple.DesiredTuple = SSB_PCMCIA_CIS; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + 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 - "PCMCIA: Failed to fetch device invariants\n"); + "PCMCIA: Failed to fetch device invariants: %s\n", + error_description); return -ENODEV; } diff --git a/trunk/drivers/staging/comedi/drivers/cb_das16_cs.c b/trunk/drivers/staging/comedi/drivers/cb_das16_cs.c index 39923cb388be..80c0df8656f3 100644 --- a/trunk/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/trunk/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -141,14 +141,37 @@ static int das16cs_timer_insn_config(struct comedi_device *dev, struct comedi_insn *insn, 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, struct pcmcia_device *link) { + int id; int i; + id = get_prodid(dev, link); + for (i = 0; i < n_boards; i++) { - if (das16cs_boards[i].device_id == link->card_id) + if (das16cs_boards[i].device_id == id) { return das16cs_boards + i; + } } printk("unknown board!\n"); @@ -637,8 +660,27 @@ 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) +#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_release(struct pcmcia_device *link); static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); @@ -691,7 +733,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link) { struct local_info_t *local; - dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n"); + DEBUG(0, "das16cs_pcmcia_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); @@ -703,6 +745,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link) /* Initialize the pcmcia_device structure */ /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; link->conf.Attributes = 0; @@ -717,7 +760,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link) static void das16cs_pcmcia_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); + DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link); if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1; @@ -728,55 +771,118 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link) kfree(link->priv); } /* 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) +static void das16cs_pcmcia_config(struct pcmcia_device *link) { - if (cfg->index == 0) - return -EINVAL; + struct local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_fn, last_ret; + u_char buf[64]; + cistpl_cftable_entry_t dflt = { 0 }; - /* 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); - } + DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link); - return 0; -} + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + 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]; -static void das16cs_pcmcia_config(struct pcmcia_device *link) -{ - struct local_info_t *dev = link->priv; - int ret; + /* + 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; - dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); +next_entry: + last_fn = GetNextTuple; - ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - goto failed; + last_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret) + goto cs_failed; } /* @@ -785,18 +891,21 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + last_fn = RequestIRQ; + + last_ret = pcmcia_request_irq(link, &link->irq); + if (last_ret) + goto cs_failed; } /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + last_fn = RequestConfiguration; + last_ret = pcmcia_request_configuration(link, &link->conf); + if (last_ret) + goto cs_failed; /* At this point, the dev_node_t structure(s) need to be @@ -821,13 +930,14 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) return; -failed: +cs_failed: + cs_error(link, last_fn, last_ret); das16cs_pcmcia_release(link); } /* das16cs_pcmcia_config */ static void das16cs_pcmcia_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); + DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link); pcmcia_disable_device(link); } /* das16cs_pcmcia_release */ @@ -873,13 +983,14 @@ struct pcmcia_driver das16cs_driver = { static int __init init_das16cs_pcmcia_cs(void) { + DEBUG(0, "%s\n", version); pcmcia_register_driver(&das16cs_driver); return 0; } static void __exit exit_das16cs_pcmcia_cs(void) { - pr_debug("das16cs_pcmcia_cs: unloading\n"); + DEBUG(0, "das16cs_pcmcia_cs: unloading\n"); pcmcia_unregister_driver(&das16cs_driver); } diff --git a/trunk/drivers/staging/comedi/drivers/das08_cs.c b/trunk/drivers/staging/comedi/drivers/das08_cs.c index 9b945e5fdd32..9cab21eaaa18 100644 --- a/trunk/drivers/staging/comedi/drivers/das08_cs.c +++ b/trunk/drivers/staging/comedi/drivers/das08_cs.c @@ -110,6 +110,25 @@ 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_release(struct pcmcia_device *link); static int das08_pcmcia_suspend(struct pcmcia_device *p_dev); @@ -162,7 +181,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) { struct local_info_t *local; - dev_dbg(&link->dev, "das08_pcmcia_attach()\n"); + DEBUG(0, "das08_pcmcia_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); @@ -173,6 +192,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; /* @@ -204,7 +224,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) static void das08_pcmcia_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "das08_pcmcia_detach\n"); + DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link); if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1; @@ -217,44 +237,6 @@ static void das08_pcmcia_detach(struct pcmcia_device *link) } /* 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 @@ -266,20 +248,128 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, static void das08_pcmcia_config(struct pcmcia_device *link) { struct local_info_t *dev = link->priv; - int ret; + tuple_t tuple; + 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); + + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + 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; - dev_dbg(&link->dev, "das08_pcmcia_config\n"); +next_entry: + last_fn = GetNextTuple; - ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - goto failed; + last_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret) + goto cs_failed; } if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + last_fn = RequestIRQ; + last_ret = pcmcia_request_irq(link, &link->irq); + if (last_ret) + goto cs_failed; } /* @@ -287,9 +377,10 @@ static void das08_pcmcia_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + last_fn = RequestConfiguration; + last_ret = pcmcia_request_configuration(link, &link->conf); + if (last_ret) + goto cs_failed; /* At this point, the dev_node_t structure(s) need to be @@ -314,7 +405,8 @@ static void das08_pcmcia_config(struct pcmcia_device *link) return; -failed: +cs_failed: + cs_error(link, last_fn, last_ret); das08_pcmcia_release(link); } /* das08_pcmcia_config */ @@ -329,7 +421,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link) static void das08_pcmcia_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "das08_pcmcia_release\n"); + DEBUG(0, "das08_pcmcia_release(0x%p)\n", link); pcmcia_disable_device(link); } /* das08_pcmcia_release */ @@ -385,13 +477,14 @@ struct pcmcia_driver das08_cs_driver = { static int __init init_das08_pcmcia_cs(void) { + DEBUG(0, "%s\n", version); pcmcia_register_driver(&das08_cs_driver); return 0; } static void __exit exit_das08_pcmcia_cs(void) { - pr_debug("das08_pcmcia_cs: unloading\n"); + DEBUG(0, "das08_pcmcia_cs: unloading\n"); pcmcia_unregister_driver(&das08_cs_driver); } diff --git a/trunk/drivers/staging/comedi/drivers/ni_daq_700.c b/trunk/drivers/staging/comedi/drivers/ni_daq_700.c index ef5e1183d47d..ec31a3970664 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/trunk/drivers/staging/comedi/drivers/ni_daq_700.c @@ -436,7 +436,25 @@ static int dio700_detach(struct comedi_device *dev) return 0; }; -/* PCMCIA crap -- watch your words, please! */ +/* PCMCIA crap */ + +/* + 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_release(struct pcmcia_device *link); @@ -492,7 +510,7 @@ static int dio700_cs_attach(struct pcmcia_device *link) printk(KERN_INFO "ni_daq_700: cs-attach\n"); - dev_dbg(&link->dev, "dio700_cs_attach()\n"); + DEBUG(0, "dio700_cs_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); @@ -503,6 +521,7 @@ static int dio700_cs_attach(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; /* @@ -536,7 +555,7 @@ static void dio700_cs_detach(struct pcmcia_device *link) printk(KERN_INFO "ni_daq_700: cs-detach!\n"); - dev_dbg(&link->dev, "dio700_cs_detach\n"); + DEBUG(0, "dio700_cs_detach(0x%p)\n", link); if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1; @@ -557,85 +576,141 @@ 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) +static void dio700_config(struct pcmcia_device *link) { - win_req_t *req = priv_data; + struct local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_ret; + u_char buf[64]; + win_req_t req; memreq_t map; + cistpl_cftable_entry_t dflt = { 0 }; - if (cfg->index == 0) - return -ENODEV; + printk(KERN_INFO "ni_daq_700: cs-config\n"); + + DEBUG(0, "dio700_config(0x%p)\n", link); - /* 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; + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + 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; } - /* 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; + last_ret = pcmcia_get_tuple_data(link, &tuple); + if (last_ret) { + cs_error(link, GetTupleData, last_ret); + goto cs_failed; } - 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; + last_ret = pcmcia_parse_tuple(&tuple, &parse); + if (last_ret) { + cs_error(link, ParseTuple, last_ret); + goto cs_failed; } - /* If we got this far, we're cool! */ - return 0; -} + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; -static void dio700_config(struct pcmcia_device *link) -{ - struct local_info_t *dev = link->priv; - win_req_t req; - int ret; + /* + 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; + } - printk(KERN_INFO "ni_daq_700: cs-config\n"); + /* 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; - dev_dbg(&link->dev, "dio700_config\n"); +next_entry: - ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, &req); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - goto failed; + last_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret) { + cs_error(link, GetNextTuple, last_ret); + goto cs_failed; + } } /* @@ -644,9 +719,11 @@ static void dio700_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + last_ret = pcmcia_request_irq(link, &link->irq); + if (last_ret) { + cs_error(link, RequestIRQ, last_ret); + goto cs_failed; + } } /* @@ -654,9 +731,11 @@ static void dio700_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret != 0) - goto failed; + last_ret = pcmcia_request_configuration(link, &link->conf); + if (last_ret != 0) { + cs_error(link, RequestConfiguration, last_ret); + goto cs_failed; + } /* At this point, the dev_node_t structure(s) need to be @@ -684,7 +763,7 @@ static void dio700_config(struct pcmcia_device *link) return; -failed: +cs_failed: printk(KERN_INFO "ni_daq_700 cs failed"); dio700_release(link); @@ -692,7 +771,7 @@ static void dio700_config(struct pcmcia_device *link) static void dio700_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "dio700_release\n"); + DEBUG(0, "dio700_release(0x%p)\n", link); pcmcia_disable_device(link); } /* dio700_release */ @@ -751,13 +830,15 @@ struct pcmcia_driver dio700_cs_driver = { 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); return 0; } static void __exit exit_dio700_cs(void) { - pr_debug("ni_daq_700: unloading\n"); + DEBUG(0, "ni_daq_700: unloading\n"); pcmcia_unregister_driver(&dio700_cs_driver); } diff --git a/trunk/drivers/staging/comedi/drivers/ni_daq_dio24.c b/trunk/drivers/staging/comedi/drivers/ni_daq_dio24.c index 9017be3a92f1..0700a8bddd1e 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/trunk/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -187,7 +187,25 @@ static int dio24_detach(struct comedi_device *dev) return 0; }; -/* PCMCIA crap -- watch your words! */ +/* PCMCIA crap */ + +/* + 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_release(struct pcmcia_device *link); @@ -243,7 +261,7 @@ static int dio24_cs_attach(struct pcmcia_device *link) printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n"); - dev_dbg(&link->dev, "dio24_cs_attach()\n"); + DEBUG(0, "dio24_cs_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); @@ -254,6 +272,7 @@ static int dio24_cs_attach(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; /* @@ -287,7 +306,7 @@ static void dio24_cs_detach(struct pcmcia_device *link) printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n"); - dev_dbg(&link->dev, "dio24_cs_detach\n"); + DEBUG(0, "dio24_cs_detach(0x%p)\n", link); if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1; @@ -308,85 +327,142 @@ 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) +static void dio24_config(struct pcmcia_device *link) { - win_req_t *req = priv_data; + struct local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_ret; + u_char buf[64]; + win_req_t req; memreq_t map; + cistpl_cftable_entry_t dflt = { 0 }; - if (cfg->index == 0) - return -ENODEV; + printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n"); + + DEBUG(0, "dio24_config(0x%p)\n", link); - /* 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; + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + 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; } - /* 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; + last_ret = pcmcia_get_tuple_data(link, &tuple); + if (last_ret) { + cs_error(link, GetTupleData, last_ret); + goto cs_failed; } - 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; + last_ret = pcmcia_parse_tuple(&tuple, &parse); + if (last_ret) { + cs_error(link, ParseTuple, last_ret); + goto cs_failed; } - /* If we got this far, we're cool! */ - return 0; -} + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; -static void dio24_config(struct pcmcia_device *link) -{ - struct local_info_t *dev = link->priv; - int ret; - win_req_t req; + /* + 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; - printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n"); + 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; + } - dev_dbg(&link->dev, "dio24_config\n"); + /* 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; - ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - goto failed; +next_entry: + + last_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret) { + cs_error(link, GetNextTuple, last_ret); + goto cs_failed; + } } /* @@ -395,9 +471,11 @@ static void dio24_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + last_ret = pcmcia_request_irq(link, &link->irq); + if (last_ret) { + cs_error(link, RequestIRQ, last_ret); + goto cs_failed; + } } /* @@ -405,9 +483,11 @@ static void dio24_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + last_ret = pcmcia_request_configuration(link, &link->conf); + if (last_ret) { + cs_error(link, RequestConfiguration, last_ret); + goto cs_failed; + } /* At this point, the dev_node_t structure(s) need to be @@ -435,7 +515,7 @@ static void dio24_config(struct pcmcia_device *link) return; -failed: +cs_failed: printk(KERN_INFO "Fallo"); dio24_release(link); @@ -443,7 +523,7 @@ static void dio24_config(struct pcmcia_device *link) static void dio24_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "dio24_release\n"); + DEBUG(0, "dio24_release(0x%p)\n", link); pcmcia_disable_device(link); } /* dio24_release */ @@ -502,12 +582,14 @@ struct pcmcia_driver dio24_cs_driver = { static int __init init_dio24_cs(void) { printk("ni_daq_dio24: HOLA SOY YO!\n"); + DEBUG(0, "%s\n", version); pcmcia_register_driver(&dio24_cs_driver); return 0; } static void __exit exit_dio24_cs(void) { + DEBUG(0, "ni_dio24: unloading\n"); pcmcia_unregister_driver(&dio24_cs_driver); } diff --git a/trunk/drivers/staging/comedi/drivers/ni_labpc_cs.c b/trunk/drivers/staging/comedi/drivers/ni_labpc_cs.c index 7d514b3ee754..a3053b8da1c6 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/trunk/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -153,6 +153,23 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) 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 + /*====================================================================*/ /* @@ -219,7 +236,7 @@ static int labpc_cs_attach(struct pcmcia_device *link) { struct local_info_t *local; - dev_dbg(&link->dev, "labpc_cs_attach()\n"); + DEBUG(0, "labpc_cs_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); @@ -230,6 +247,7 @@ static int labpc_cs_attach(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID; link->irq.Handler = NULL; /* @@ -260,7 +278,7 @@ static int labpc_cs_attach(struct pcmcia_device *link) static void labpc_cs_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "labpc_cs_detach\n"); + DEBUG(0, "labpc_cs_detach(0x%p)\n", link); /* If the device is currently configured and active, we won't @@ -287,84 +305,135 @@ 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) +static void labpc_config(struct pcmcia_device *link) { - win_req_t *req = priv_data; + struct local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_ret; + u_char buf[64]; + win_req_t req; memreq_t map; + cistpl_cftable_entry_t dflt = { 0 }; - if (cfg->index == 0) - return -ENODEV; + DEBUG(0, "labpc_config(0x%p)\n", link); - /* 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; + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + 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; } - /* 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; + last_ret = pcmcia_get_tuple_data(link, &tuple); + if (last_ret) { + cs_error(link, GetTupleData, last_ret); + goto cs_failed; } - 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; + last_ret = pcmcia_parse_tuple(&tuple, &parse); + if (last_ret) { + cs_error(link, ParseTuple, last_ret); + goto cs_failed; } - /* If we got this far, we're cool! */ - return 0; -} + 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; + } -static void labpc_config(struct pcmcia_device *link) -{ - struct local_info_t *dev = link->priv; - int ret; - win_req_t req; + /* 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; + } - dev_dbg(&link->dev, "labpc_config\n"); + 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; - ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, &req); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - goto failed; +next_entry: + last_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret) { + cs_error(link, GetNextTuple, last_ret); + goto cs_failed; + } } /* @@ -373,9 +442,11 @@ static void labpc_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + last_ret = pcmcia_request_irq(link, &link->irq); + if (last_ret) { + cs_error(link, RequestIRQ, last_ret); + goto cs_failed; + } } /* @@ -383,9 +454,11 @@ static void labpc_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + last_ret = pcmcia_request_configuration(link, &link->conf); + if (last_ret) { + cs_error(link, RequestConfiguration, last_ret); + goto cs_failed; + } /* At this point, the dev_node_t structure(s) need to be @@ -413,14 +486,14 @@ static void labpc_config(struct pcmcia_device *link) return; -failed: +cs_failed: labpc_release(link); } /* labpc_config */ static void labpc_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "labpc_release\n"); + DEBUG(0, "labpc_release(0x%p)\n", link); pcmcia_disable_device(link); } /* labpc_release */ @@ -478,12 +551,14 @@ struct pcmcia_driver labpc_cs_driver = { static int __init init_labpc_cs(void) { + DEBUG(0, "%s\n", version); pcmcia_register_driver(&labpc_cs_driver); return 0; } static void __exit exit_labpc_cs(void) { + DEBUG(0, "ni_labpc: unloading\n"); pcmcia_unregister_driver(&labpc_cs_driver); } diff --git a/trunk/drivers/staging/comedi/drivers/ni_mio_cs.c b/trunk/drivers/staging/comedi/drivers/ni_mio_cs.c index d692f4bb47ea..9aef87fc81dc 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/trunk/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -274,6 +274,7 @@ static int cs_attach(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.NumPorts1 = 16; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -311,47 +312,96 @@ static int mio_cs_resume(struct pcmcia_device *link) 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) +static void mio_cs_config(struct pcmcia_device *link) { - int base, ret; + tuple_t tuple; + u_short buf[128]; + cisparse_t parse; + int manfid = 0, prodid = 0; + int ret; + + DPRINTK("mio_cs_config(link=%p)\n", link); + + tuple.TupleData = (cisdata_t *) buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; - 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; + 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]; - 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; +#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]); } - return -ENODEV; -} + /* 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); -static void mio_cs_config(struct pcmcia_device *link) -{ - int ret; +#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 - DPRINTK("mio_cs_config(link=%p)\n", link); +#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; - ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - return; + { + 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); if (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); + /* printk("RequestConfiguration %d\n",ret); */ link->dev_node = &dev_node; } @@ -425,17 +475,40 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) 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, struct pcmcia_device *link) { + int id; int i; + id = get_prodid(dev, link); + for (i = 0; i < n_ni_boards; i++) { - if (ni_boards[i].device_id == link->card_id) + if (ni_boards[i].device_id == id) { return i; + } } - printk("unknown board 0x%04x -- pretend it is a ", link->card_id); + printk("unknown board 0x%04x -- pretend it is a ", id); return 0; } diff --git a/trunk/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/trunk/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 5256fd933162..344b82353e08 100644 --- a/trunk/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/trunk/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -55,6 +55,23 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 #include #include +/* + 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 = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)"; +#else +#define DEBUG(n, args...) +#endif + /* Maximum number of separate DAQP devices we'll allow */ #define MAX_DEV 4 @@ -846,6 +863,8 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; struct local_info_t *local = dev_table[it->options[0]]; + tuple_t tuple; + int i; struct comedi_subdevice *s; if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) { @@ -864,10 +883,29 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) strcpy(local->board_name, "DAQP"); dev->board_name = local->board_name; - if (local->link->prod_id[2]) { - if (strncmp(local->link->prod_id[2], "DAQP", 4) == 0) { - strncpy(local->board_name, local->link->prod_id[2], - sizeof(local->board_name)); + + tuple.DesiredTuple = CISTPL_VERS_1; + if (pcmcia_get_first_tuple(local->link, &tuple) == 0) { + u_char buf[128]; + + buf[0] = buf[sizeof(buf) - 1] = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 2; + if (pcmcia_get_tuple_data(local->link, &tuple) == 0) { + + for (i = 0; i < tuple.TupleDataLen - 4; i++) + if (buf[i] == 0) + break; + for (i++; i < tuple.TupleDataLen - 4; i++) + if (buf[i] == 0) + break; + i++; + if ((i < tuple.TupleDataLen - 4) + && (strncmp(buf + i, "DAQP", 4) == 0)) { + strncpy(local->board_name, buf + i, + sizeof(local->board_name)); + } } } @@ -1020,7 +1058,7 @@ static int daqp_cs_attach(struct pcmcia_device *link) struct local_info_t *local; int i; - dev_dbg(&link->dev, "daqp_cs_attach()\n"); + DEBUG(0, "daqp_cs_attach()\n"); for (i = 0; i < MAX_DEV; i++) if (dev_table[i] == NULL) @@ -1041,8 +1079,10 @@ static int daqp_cs_attach(struct pcmcia_device *link) link->priv = local; /* Interrupt setup */ - 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 = daqp_interrupt; + link->irq.Instance = local; /* General socket configuration defaults can go here. In this @@ -1072,7 +1112,7 @@ static void daqp_cs_detach(struct pcmcia_device *link) { struct local_info_t *dev = link->priv; - dev_dbg(&link->dev, "daqp_cs_detach\n"); + DEBUG(0, "daqp_cs_detach(0x%p)\n", link); if (link->dev_node) { dev->stop = 1; @@ -1094,54 +1134,115 @@ static void daqp_cs_detach(struct pcmcia_device *link) ======================================================================*/ - -static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static void daqp_cs_config(struct pcmcia_device *link) { - if (cfg->index == 0) - return -ENODEV; + struct local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_ret; + u_char buf[64]; - /* 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; - } + DEBUG(0, "daqp_cs_config(0x%p)\n", link); + + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + 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; } - /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); -} + last_ret = pcmcia_get_tuple_data(link, &tuple); + if (last_ret) { + cs_error(link, GetTupleData, last_ret); + goto cs_failed; + } -static void daqp_cs_config(struct pcmcia_device *link) -{ - struct local_info_t *dev = link->priv; - int ret; + 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]; - dev_dbg(&link->dev, "daqp_cs_config\n"); + /* + 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; + } - ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - goto failed; + while (1) { + cistpl_cftable_entry_t dflt = { 0 }; + 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; + + /* 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_ret = pcmcia_get_next_tuple(link, &tuple); + if (last_ret) { + cs_error(link, GetNextTuple, last_ret); + goto cs_failed; + } } /* @@ -1150,9 +1251,11 @@ static void daqp_cs_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; + last_ret = pcmcia_request_irq(link, &link->irq); + if (last_ret) { + cs_error(link, RequestIRQ, last_ret); + goto cs_failed; + } } /* @@ -1160,9 +1263,11 @@ static void daqp_cs_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + last_ret = pcmcia_request_configuration(link, &link->conf); + if (last_ret) { + cs_error(link, RequestConfiguration, last_ret); + goto cs_failed; + } /* At this point, the dev_node_t structure(s) need to be @@ -1191,14 +1296,14 @@ static void daqp_cs_config(struct pcmcia_device *link) return; -failed: +cs_failed: daqp_cs_release(link); } /* daqp_cs_config */ static void daqp_cs_release(struct pcmcia_device *link) { - dev_dbg(&link->dev, "daqp_cs_release\n"); + DEBUG(0, "daqp_cs_release(0x%p)\n", link); pcmcia_disable_device(link); } /* daqp_cs_release */ @@ -1258,6 +1363,7 @@ struct pcmcia_driver daqp_cs_driver = { int __init init_module(void) { + DEBUG(0, "%s\n", version); pcmcia_register_driver(&daqp_cs_driver); comedi_driver_register(&driver_daqp); return 0; @@ -1265,6 +1371,7 @@ int __init init_module(void) void __exit cleanup_module(void) { + DEBUG(0, "daqp_cs: unloading\n"); comedi_driver_unregister(&driver_daqp); pcmcia_unregister_driver(&daqp_cs_driver); } diff --git a/trunk/drivers/telephony/ixj_pcmcia.c b/trunk/drivers/telephony/ixj_pcmcia.c index d442fd35620a..347c3ed1d9f1 100644 --- a/trunk/drivers/telephony/ixj_pcmcia.c +++ b/trunk/drivers/telephony/ixj_pcmcia.c @@ -19,6 +19,13 @@ * PCMCIA service support for Quicknet cards */ +#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) +#else +#define DEBUG(n, args...) +#endif typedef struct ixj_info_t { int ndev; @@ -32,7 +39,7 @@ static void ixj_cs_release(struct pcmcia_device * link); static int ixj_probe(struct pcmcia_device *p_dev) { - dev_dbg(&p_dev->dev, "ixj_attach()\n"); + DEBUG(0, "ixj_attach()\n"); /* Create new ixj device */ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8; @@ -48,30 +55,33 @@ static int ixj_probe(struct pcmcia_device *p_dev) static void ixj_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "ixj_detach\n"); + DEBUG(0, "ixj_detach(0x%p)\n", link); ixj_cs_release(link); kfree(link->priv); } +#define CS_CHECK(fn, ret) \ +do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) + static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) { char *str; int i, place; - dev_dbg(&link->dev, "ixj_get_serial\n"); + DEBUG(0, "ixj_get_serial(0x%p)\n", link); str = link->prod_id[0]; if (!str) - goto failed; + goto cs_failed; printk("%s", str); str = link->prod_id[1]; if (!str) - goto failed; + goto cs_failed; printk(" %s", str); str = link->prod_id[2]; if (!str) - goto failed; + goto cs_failed; place = 1; for (i = strlen(str) - 1; i >= 0; i--) { switch (str[i]) { @@ -108,9 +118,9 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) } str = link->prod_id[3]; if (!str) - goto failed; + goto cs_failed; printk(" version %s\n", str); -failed: + cs_failed: return; } @@ -141,13 +151,13 @@ static int ixj_config(struct pcmcia_device * link) cistpl_cftable_entry_t dflt = { 0 }; info = link->priv; - dev_dbg(&link->dev, "ixj_config\n"); + DEBUG(0, "ixj_config(0x%p)\n", link); if (pcmcia_loop_config(link, ixj_config_check, &dflt)) - goto failed; + goto cs_failed; if (pcmcia_request_configuration(link, &link->conf)) - goto failed; + goto cs_failed; /* * Register the card with the core. @@ -160,7 +170,7 @@ static int ixj_config(struct pcmcia_device * link) ixj_get_serial(link, j); return 0; -failed: + cs_failed: ixj_cs_release(link); return -ENODEV; } @@ -168,7 +178,7 @@ static int ixj_config(struct pcmcia_device * link) static void ixj_cs_release(struct pcmcia_device *link) { ixj_info_t *info = link->priv; - dev_dbg(&link->dev, "ixj_cs_release\n"); + DEBUG(0, "ixj_cs_release(0x%p)\n", link); info->ndev = 0; pcmcia_disable_device(link); } diff --git a/trunk/drivers/usb/host/sl811_cs.c b/trunk/drivers/usb/host/sl811_cs.c index 39d253e841f6..516848dd9b48 100644 --- a/trunk/drivers/usb/host/sl811_cs.c +++ b/trunk/drivers/usb/host/sl811_cs.c @@ -37,8 +37,28 @@ MODULE_LICENSE("GPL"); /* MACROS */ /*====================================================================*/ +#if defined(DEBUG) || defined(PCMCIA_DEBUG) + +static int pc_debug = 0; +module_param(pc_debug, int, 0644); + +#define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) + +#else +#define DBG(n, args...) do{}while(0) +#endif /* no debugging */ + #define INFO(args...) printk(KERN_INFO "sl811_cs: " args) +#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) + +#define CS_CHECK(fn, ret) \ + do { \ + last_fn = (fn); \ + if ((last_ret = (ret)) != 0) \ + goto cs_failed; \ + } while (0) + /*====================================================================*/ /* VARIABLES */ /*====================================================================*/ @@ -56,7 +76,7 @@ static void sl811_cs_release(struct pcmcia_device * link); static void release_platform_dev(struct device * dev) { - dev_dbg(dev, "sl811_cs platform_dev release\n"); + DBG(0, "sl811_cs platform_dev release\n"); dev->parent = NULL; } @@ -120,7 +140,7 @@ static int sl811_hc_init(struct device *parent, resource_size_t base_addr, static void sl811_cs_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "sl811_cs_detach\n"); + DBG(0, "sl811_cs_detach(0x%p)\n", link); sl811_cs_release(link); @@ -130,7 +150,7 @@ static void sl811_cs_detach(struct pcmcia_device *link) static void sl811_cs_release(struct pcmcia_device * link) { - dev_dbg(&link->dev, "sl811_cs_release\n"); + DBG(0, "sl811_cs_release(0x%p)\n", link); pcmcia_disable_device(link); platform_device_unregister(&platform_dev); @@ -185,11 +205,11 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev, static int sl811_cs_config(struct pcmcia_device *link) { - struct device *parent = &link->dev; + struct device *parent = &handle_to_dev(link); local_info_t *dev = link->priv; - int ret; + int last_fn, last_ret; - dev_dbg(&link->dev, "sl811_cs_config\n"); + DBG(0, "sl811_cs_config(0x%p)\n", link); if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) goto failed; @@ -197,16 +217,14 @@ static int sl811_cs_config(struct pcmcia_device *link) /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) goto failed; - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - } else + if (link->conf.Attributes & CONF_ENABLE_IRQ) + CS_CHECK(RequestIRQ, + pcmcia_request_irq(link, &link->irq)); + else goto failed; - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; + CS_CHECK(RequestConfiguration, + pcmcia_request_configuration(link, &link->conf)); sprintf(dev->node.dev_name, driver_name); dev->node.major = dev->node.minor = 0; @@ -223,6 +241,8 @@ static int sl811_cs_config(struct pcmcia_device *link) if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { +cs_failed: + cs_error(link, last_fn, last_ret); failed: printk(KERN_WARNING "sl811_cs_config failed\n"); sl811_cs_release(link); @@ -243,6 +263,7 @@ static int sl811_cs_probe(struct pcmcia_device *link) /* Initialize */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; link->irq.Handler = NULL; link->conf.Attributes = 0; diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index c0c636e34f60..ba112bd4a339 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -1206,6 +1207,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) struct linux_binfmt *fmt; retval = security_bprm_check(bprm); + if (retval) + return retval; + retval = ima_bprm_check(bprm); if (retval) return retval; diff --git a/trunk/fs/file_table.c b/trunk/fs/file_table.c index 4bef4c01ec6f..8eb44042e009 100644 --- a/trunk/fs/file_table.c +++ b/trunk/fs/file_table.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -279,6 +280,7 @@ void __fput(struct file *file) if (file->f_op && file->f_op->release) file->f_op->release(inode, file); security_file_free(file); + ima_file_free(file); if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) cdev_put(inode->i_cdev); fops_put(file->f_op); diff --git a/trunk/fs/gfs2/glock.c b/trunk/fs/gfs2/glock.c index 8b674b1f3a55..a3f90ad2af80 100644 --- a/trunk/fs/gfs2/glock.c +++ b/trunk/fs/gfs2/glock.c @@ -672,12 +672,17 @@ __acquires(&gl->gl_spin) return; out_sched: + clear_bit(GLF_LOCK, &gl->gl_flags); + smp_mb__after_clear_bit(); gfs2_glock_hold(gl); if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) gfs2_glock_put_nolock(gl); + return; + out_unlock: clear_bit(GLF_LOCK, &gl->gl_flags); - goto out; + smp_mb__after_clear_bit(); + return; } static void delete_work_func(struct work_struct *work) @@ -1375,10 +1380,11 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask) handle_callback(gl, LM_ST_UNLOCKED, 0); nr--; } + clear_bit(GLF_LOCK, &gl->gl_flags); + smp_mb__after_clear_bit(); if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) gfs2_glock_put_nolock(gl); spin_unlock(&gl->gl_spin); - clear_bit(GLF_LOCK, &gl->gl_flags); spin_lock(&lru_lock); continue; } diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 06c1f02de611..4d8e3be55976 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -156,6 +157,11 @@ int inode_init_always(struct super_block *sb, struct inode *inode) if (security_inode_alloc(inode)) goto out; + + /* allocate and initialize an i_integrity */ + if (ima_inode_alloc(inode)) + goto out_free_security; + spin_lock_init(&inode->i_lock); lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key); @@ -195,6 +201,9 @@ int inode_init_always(struct super_block *sb, struct inode *inode) #endif return 0; + +out_free_security: + security_inode_free(inode); out: return -ENOMEM; } @@ -226,6 +235,7 @@ static struct inode *alloc_inode(struct super_block *sb) void __destroy_inode(struct inode *inode) { BUG_ON(inode_has_buffers(inode)); + ima_inode_free(inode); security_inode_free(inode); fsnotify_inode_delete(inode); #ifdef CONFIG_FS_POSIX_ACL diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 7d70d63ceb29..bdc3cb4fd222 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -1921,16 +1921,6 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, if (data_page) ((char *)data_page)[PAGE_SIZE - 1] = 0; - /* ... and get the mountpoint */ - retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); - if (retval) - return retval; - - retval = security_sb_mount(dev_name, &path, - type_page, flags, data_page); - if (retval) - goto dput_out; - /* Default to relatime unless overriden */ if (!(flags & MS_NOATIME)) mnt_flags |= MNT_RELATIME; @@ -1955,6 +1945,16 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | MS_STRICTATIME); + /* ... and get the mountpoint */ + retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); + if (retval) + return retval; + + retval = security_sb_mount(dev_name, &path, + type_page, flags, data_page); + if (retval) + goto dput_out; + if (flags & MS_REMOUNT) retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, data_page); diff --git a/trunk/fs/open.c b/trunk/fs/open.c index b4b31d277f3a..4f01e06227c6 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -587,9 +587,6 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename) error = -EPERM; if (!capable(CAP_SYS_CHROOT)) goto dput_and_out; - error = security_path_chroot(&path); - if (error) - goto dput_and_out; set_fs_root(current->fs, &path); error = 0; @@ -620,15 +617,11 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode) if (err) goto out_putf; mutex_lock(&inode->i_mutex); - err = security_path_chmod(dentry, file->f_vfsmnt, mode); - if (err) - goto out_unlock; if (mode == (mode_t) -1) mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; err = notify_change(dentry, &newattrs); -out_unlock: mutex_unlock(&inode->i_mutex); mnt_drop_write(file->f_path.mnt); out_putf: @@ -653,15 +646,11 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode) if (error) goto dput_and_out; mutex_lock(&inode->i_mutex); - error = security_path_chmod(path.dentry, path.mnt, mode); - if (error) - goto out_unlock; if (mode == (mode_t) -1) mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; error = notify_change(path.dentry, &newattrs); -out_unlock: mutex_unlock(&inode->i_mutex); mnt_drop_write(path.mnt); dput_and_out: @@ -675,9 +664,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode) return sys_fchmodat(AT_FDCWD, filename, mode); } -static int chown_common(struct path *path, uid_t user, gid_t group) +static int chown_common(struct dentry * dentry, uid_t user, gid_t group) { - struct inode *inode = path->dentry->d_inode; + struct inode *inode = dentry->d_inode; int error; struct iattr newattrs; @@ -694,9 +683,7 @@ static int chown_common(struct path *path, uid_t user, gid_t group) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; mutex_lock(&inode->i_mutex); - error = security_path_chown(path, user, group); - if (!error) - error = notify_change(path->dentry, &newattrs); + error = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); return error; @@ -713,7 +700,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(&path, user, group); + error = chown_common(path.dentry, user, group); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -738,7 +725,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(&path, user, group); + error = chown_common(path.dentry, user, group); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -757,7 +744,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(&path, user, group); + error = chown_common(path.dentry, user, group); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -780,7 +767,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) goto out_fput; dentry = file->f_path.dentry; audit_inode(NULL, dentry); - error = chown_common(&file->f_path, user, group); + error = chown_common(dentry, user, group); mnt_drop_write(file->f_path.mnt); out_fput: fput(file); diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index 5a5385749e16..1feed71551c9 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -330,7 +330,6 @@ unifdef-y += scc.h unifdef-y += sched.h unifdef-y += screen_info.h unifdef-y += sdla.h -unifdef-y += securebits.h unifdef-y += selinux_netlink.h unifdef-y += sem.h unifdef-y += serial_core.h diff --git a/trunk/include/linux/capability.h b/trunk/include/linux/capability.h index 39e5ff512fbe..c8f2a5f70ed5 100644 --- a/trunk/include/linux/capability.h +++ b/trunk/include/linux/capability.h @@ -92,7 +92,9 @@ struct vfs_cap_data { #define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3 #define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES extern int file_caps_enabled; +#endif typedef struct kernel_cap_struct { __u32 cap[_KERNEL_CAPABILITY_U32S]; diff --git a/trunk/include/linux/compiler-gcc4.h b/trunk/include/linux/compiler-gcc4.h index ab3af40a53c6..450fa597c94d 100644 --- a/trunk/include/linux/compiler-gcc4.h +++ b/trunk/include/linux/compiler-gcc4.h @@ -36,18 +36,4 @@ the kernel context */ #define __cold __attribute__((__cold__)) - -#if __GNUC_MINOR__ >= 5 -/* - * Mark a position in code as unreachable. This can be used to - * suppress control flow warnings after asm blocks that transfer - * control elsewhere. - * - * Early snapshots of gcc 4.5 don't support this and we can't detect - * this in the preprocessor, but we can live with this because they're - * unreleased. Really, we need to have autoconf for the kernel. - */ -#define unreachable() __builtin_unreachable() -#endif - #endif diff --git a/trunk/include/linux/compiler.h b/trunk/include/linux/compiler.h index 59f208926d13..04fb5135b4e1 100644 --- a/trunk/include/linux/compiler.h +++ b/trunk/include/linux/compiler.h @@ -144,11 +144,6 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); # define barrier() __memory_barrier() #endif -/* Unreachable code */ -#ifndef unreachable -# define unreachable() do { } while (1) -#endif - #ifndef RELOC_HIDE # define RELOC_HIDE(ptr, off) \ ({ unsigned long __ptr; \ diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index 8d10aa7fd4c9..21a6f5d9af22 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -83,12 +83,16 @@ extern struct group_info init_groups; #define INIT_IDS #endif +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES /* * Because of the reduced scope of CAP_SETPCAP when filesystem * capabilities are in effect, it is safe to allow CAP_SETPCAP to * be available in the default configuration. */ # define CAP_INIT_BSET CAP_FULL_SET +#else +# define CAP_INIT_BSET CAP_INIT_EFF_SET +#endif #ifdef CONFIG_TREE_PREEMPT_RCU #define INIT_TASK_RCU_PREEMPT(tsk) \ diff --git a/trunk/include/linux/lsm_audit.h b/trunk/include/linux/lsm_audit.h index f78f83d7663f..190c37854870 100644 --- a/trunk/include/linux/lsm_audit.h +++ b/trunk/include/linux/lsm_audit.h @@ -26,15 +26,14 @@ /* Auxiliary data to use in generating the audit record. */ struct common_audit_data { - char type; -#define LSM_AUDIT_DATA_FS 1 -#define LSM_AUDIT_DATA_NET 2 -#define LSM_AUDIT_DATA_CAP 3 -#define LSM_AUDIT_DATA_IPC 4 -#define LSM_AUDIT_DATA_TASK 5 -#define LSM_AUDIT_DATA_KEY 6 -#define LSM_AUDIT_NO_AUDIT 7 -#define LSM_AUDIT_DATA_KMOD 8 + char type; +#define LSM_AUDIT_DATA_FS 1 +#define LSM_AUDIT_DATA_NET 2 +#define LSM_AUDIT_DATA_CAP 3 +#define LSM_AUDIT_DATA_IPC 4 +#define LSM_AUDIT_DATA_TASK 5 +#define LSM_AUDIT_DATA_KEY 6 +#define LSM_AUDIT_NO_AUDIT 7 struct task_struct *tsk; union { struct { @@ -67,7 +66,6 @@ struct common_audit_data { char *key_desc; } key_struct; #endif - char *kmod_name; } u; /* this union contains LSM specific data */ union { diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index daecca3c8300..84cf1f3b7838 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1633,8 +1633,6 @@ #define PCI_DEVICE_ID_O2_6730 0x673a #define PCI_DEVICE_ID_O2_6832 0x6832 #define PCI_DEVICE_ID_O2_6836 0x6836 -#define PCI_DEVICE_ID_O2_6812 0x6872 -#define PCI_DEVICE_ID_O2_6933 0x6933 #define PCI_VENDOR_ID_3DFX 0x121a #define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 diff --git a/trunk/include/linux/securebits.h b/trunk/include/linux/securebits.h index 33406174cbe8..d2c5ed845bcc 100644 --- a/trunk/include/linux/securebits.h +++ b/trunk/include/linux/securebits.h @@ -1,15 +1,6 @@ #ifndef _LINUX_SECUREBITS_H #define _LINUX_SECUREBITS_H 1 -/* Each securesetting is implemented using two bits. One bit specifies - whether the setting is on or off. The other bit specify whether the - setting is locked or not. A setting which is locked cannot be - changed from user-level. */ -#define issecure_mask(X) (1 << (X)) -#ifdef __KERNEL__ -#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits)) -#endif - #define SECUREBITS_DEFAULT 0x00000000 /* When set UID 0 has no special privileges. When unset, we support @@ -21,9 +12,6 @@ #define SECURE_NOROOT 0 #define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */ -#define SECBIT_NOROOT (issecure_mask(SECURE_NOROOT)) -#define SECBIT_NOROOT_LOCKED (issecure_mask(SECURE_NOROOT_LOCKED)) - /* When set, setuid to/from uid 0 does not trigger capability-"fixup". When unset, to provide compatiblility with old programs relying on set*uid to gain/lose privilege, transitions to/from uid 0 cause @@ -31,10 +19,6 @@ #define SECURE_NO_SETUID_FIXUP 2 #define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */ -#define SECBIT_NO_SETUID_FIXUP (issecure_mask(SECURE_NO_SETUID_FIXUP)) -#define SECBIT_NO_SETUID_FIXUP_LOCKED \ - (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED)) - /* When set, a process can retain its capabilities even after transitioning to a non-root user (the set-uid fixup suppressed by bit 2). Bit-4 is cleared when a process calls exec(); setting both @@ -43,8 +27,12 @@ #define SECURE_KEEP_CAPS 4 #define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4 immutable */ -#define SECBIT_KEEP_CAPS (issecure_mask(SECURE_KEEP_CAPS)) -#define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED)) +/* Each securesetting is implemented using two bits. One bit specifies + whether the setting is on or off. The other bit specify whether the + setting is locked or not. A setting which is locked cannot be + changed from user-level. */ +#define issecure_mask(X) (1 << (X)) +#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits)) #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ issecure_mask(SECURE_NO_SETUID_FIXUP) | \ diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index 466cbadbd1ef..239e40d0450b 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -447,22 +447,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @new_dir contains the path structure for parent of the new link. * @new_dentry contains the dentry structure of the new link. * Return 0 if permission is granted. - * @path_chmod: - * Check for permission to change DAC's permission of a file or directory. - * @dentry contains the dentry structure. - * @mnt contains the vfsmnt structure. - * @mode contains DAC's mode. - * Return 0 if permission is granted. - * @path_chown: - * Check for permission to change owner/group of a file or directory. - * @path contains the path structure. - * @uid contains new owner's ID. - * @gid contains new group's ID. - * Return 0 if permission is granted. - * @path_chroot: - * Check for permission to change root directory. - * @path contains the path structure. - * Return 0 if permission is granted. * @inode_readlink: * Check the permission to read the symbolic link. * @dentry contains the dentry structure for the file link. @@ -706,7 +690,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @kernel_module_request: * Ability to trigger the kernel to automatically upcall to userspace for * userspace to load a kernel module with the given name. - * @kmod_name name of the module requested by the kernel * Return 0 if successful. * @task_setuid: * Check permission before setting one or more of the user identity @@ -1505,10 +1488,6 @@ struct security_operations { struct dentry *new_dentry); int (*path_rename) (struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry); - int (*path_chmod) (struct dentry *dentry, struct vfsmount *mnt, - mode_t mode); - int (*path_chown) (struct path *path, uid_t uid, gid_t gid); - int (*path_chroot) (struct path *path); #endif int (*inode_alloc_security) (struct inode *inode); @@ -1578,7 +1557,7 @@ struct security_operations { void (*cred_transfer)(struct cred *new, const struct cred *old); int (*kernel_act_as)(struct cred *new, u32 secid); int (*kernel_create_files_as)(struct cred *new, struct inode *inode); - int (*kernel_module_request)(char *kmod_name); + int (*kernel_module_request)(void); int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags); int (*task_fix_setuid) (struct cred *new, const struct cred *old, int flags); @@ -1843,7 +1822,7 @@ void security_commit_creds(struct cred *new, const struct cred *old); void security_transfer_creds(struct cred *new, const struct cred *old); int security_kernel_act_as(struct cred *new, u32 secid); int security_kernel_create_files_as(struct cred *new, struct inode *inode); -int security_kernel_module_request(char *kmod_name); +int security_kernel_module_request(void); int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags); int security_task_fix_setuid(struct cred *new, const struct cred *old, int flags); @@ -2408,7 +2387,7 @@ static inline int security_kernel_create_files_as(struct cred *cred, return 0; } -static inline int security_kernel_module_request(char *kmod_name) +static inline int security_kernel_module_request(void) { return 0; } @@ -2973,10 +2952,6 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry); int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry); -int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt, - mode_t mode); -int security_path_chown(struct path *path, uid_t uid, gid_t gid); -int security_path_chroot(struct path *path); #else /* CONFIG_SECURITY_PATH */ static inline int security_path_unlink(struct path *dir, struct dentry *dentry) { @@ -3026,23 +3001,6 @@ static inline int security_path_rename(struct path *old_dir, { return 0; } - -static inline int security_path_chmod(struct dentry *dentry, - struct vfsmount *mnt, - mode_t mode) -{ - return 0; -} - -static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid) -{ - return 0; -} - -static inline int security_path_chroot(struct path *path) -{ - return 0; -} #endif /* CONFIG_SECURITY_PATH */ #ifdef CONFIG_KEYS diff --git a/trunk/include/linux/tpm.h b/trunk/include/linux/tpm.h index ac5d1c1285d9..3338b3f5c21a 100644 --- a/trunk/include/linux/tpm.h +++ b/trunk/include/linux/tpm.h @@ -27,16 +27,9 @@ */ #define TPM_ANY_NUM 0xFFFF -#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) +#if defined(CONFIG_TCG_TPM) extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash); -#else -static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { - return -ENODEV; -} -static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) { - return -ENODEV; -} #endif #endif diff --git a/trunk/include/pcmcia/cs.h b/trunk/include/pcmcia/cs.h index afc2bfb9e917..904468a191ef 100644 --- a/trunk/include/pcmcia/cs.h +++ b/trunk/include/pcmcia/cs.h @@ -15,10 +15,6 @@ #ifndef _LINUX_CS_H #define _LINUX_CS_H -#ifdef __KERNEL__ -#include -#endif - /* For AccessConfigurationRegister */ typedef struct conf_reg_t { u_char Function; @@ -115,9 +111,11 @@ typedef struct io_req_t { /* For RequestIRQ and ReleaseIRQ */ typedef struct irq_req_t { - u_int Attributes; - u_int AssignedIRQ; - irq_handler_t Handler; + u_int Attributes; + u_int AssignedIRQ; + u_int IRQInfo1, IRQInfo2; /* IRQInfo2 is ignored */ + void *Handler; + void *Instance; } irq_req_t; /* Attributes for RequestIRQ and ReleaseIRQ */ @@ -127,7 +125,7 @@ typedef struct irq_req_t { #define IRQ_TYPE_DYNAMIC_SHARING 0x02 #define IRQ_FORCED_PULSE 0x04 #define IRQ_FIRST_SHARED 0x08 -//#define IRQ_HANDLE_PRESENT 0x10 +#define IRQ_HANDLE_PRESENT 0x10 #define IRQ_PULSE_ALLOCATED 0x100 /* Bits in IRQInfo1 field */ diff --git a/trunk/include/pcmcia/cs_types.h b/trunk/include/pcmcia/cs_types.h index f5e3b8386c8f..315965a37930 100644 --- a/trunk/include/pcmcia/cs_types.h +++ b/trunk/include/pcmcia/cs_types.h @@ -26,7 +26,8 @@ typedef u_int event_t; typedef u_char cisdata_t; typedef u_short page_t; -typedef unsigned long window_handle_t; +struct window_t; +typedef struct window_t *window_handle_t; struct region_t; typedef struct region_t *memory_handle_t; diff --git a/trunk/include/pcmcia/ds.h b/trunk/include/pcmcia/ds.h index d403c12f7978..a2be80b9a095 100644 --- a/trunk/include/pcmcia/ds.h +++ b/trunk/include/pcmcia/ds.h @@ -34,7 +34,6 @@ struct pcmcia_socket; struct pcmcia_device; struct config_t; -struct net_device; /* dynamic device IDs for PCMCIA device drivers. See * Documentation/pcmcia/driver.txt for details. @@ -138,38 +137,64 @@ struct pcmcia_device { #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev) #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv) +/* deprecated -- don't use! */ +#define handle_to_dev(handle) (handle->dev) -/* - * CIS access. - * - * Please use the following functions to access CIS tuples: - * - pcmcia_get_tuple() - * - pcmcia_loop_tuple() - * - pcmcia_get_mac_from_cis() - * - * To parse a tuple_t, pcmcia_parse_tuple() exists. Its interface - * might change in future. - */ -/* get the very first CIS entry of type @code. Note that buf is pointer - * to u8 *buf; and that you need to kfree(buf) afterwards. */ -size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, - u8 **buf); +/* (deprecated) error reporting by PCMCIA devices. Use dev_printk() + * or dev_dbg() directly in the driver, without referring to pcmcia_error_func() + * and/or pcmcia_error_ret() for those functions will go away soon. + */ +enum service { + AccessConfigurationRegister, AddSocketServices, + AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory, + DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo, + GetClientInfo, GetConfigurationInfo, GetEventMask, + GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple, + GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple, + GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage, + MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow, + OpenMemory, ParseTuple, ReadMemory, RegisterClient, + RegisterEraseQueue, RegisterMTD, RegisterTimer, + ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ, + ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices, + RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ, + RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry, + SetEventMask, SetRegion, ValidateCIS, VendorSpecific, + WriteMemory, BindDevice, BindMTD, ReportError, + SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS, + GetFirstWindow, GetNextWindow, GetMemPage +}; +const char *pcmcia_error_func(int func); +const char *pcmcia_error_ret(int ret); + +#define cs_error(p_dev, func, ret) \ + { \ + dev_printk(KERN_NOTICE, &p_dev->dev, \ + "%s : %s\n", \ + pcmcia_error_func(func), \ + pcmcia_error_ret(ret)); \ + } + +/* CIS access. + * Use the pcmcia_* versions in PCMCIA drivers + */ +int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse); -/* loop over CIS entries */ -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); +int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, + tuple_t *tuple); +#define pcmcia_get_first_tuple(p_dev, tuple) \ + pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple) -/* get the MAC address from CISTPL_FUNCE */ -int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, - struct net_device *dev); +int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, + tuple_t *tuple); +#define pcmcia_get_next_tuple(p_dev, tuple) \ + pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple) +int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); +#define pcmcia_get_tuple_data(p_dev, tuple) \ + pccard_get_tuple_data(p_dev->socket, tuple) -/* parse a tuple_t */ -int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse); /* loop CIS entries for valid configuration */ int pcmcia_loop_config(struct pcmcia_device *p_dev, @@ -196,11 +221,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req); int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req); -int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, +int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh); -int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t win); -int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t win, - memreq_t *req); +int pcmcia_release_window(window_handle_t win); + +int pcmcia_get_mem_page(window_handle_t win, memreq_t *req); +int pcmcia_map_mem_page(window_handle_t win, memreq_t *req); int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); void pcmcia_disable_device(struct pcmcia_device *p_dev); diff --git a/trunk/include/pcmcia/ss.h b/trunk/include/pcmcia/ss.h index 7c23be706f12..e0f6feb8588c 100644 --- a/trunk/include/pcmcia/ss.h +++ b/trunk/include/pcmcia/ss.h @@ -107,6 +107,15 @@ typedef struct io_window_t { struct resource *res; } io_window_t; +#define WINDOW_MAGIC 0xB35C +typedef struct window_t { + u_short magic; + u_short index; + struct pcmcia_device *handle; + struct pcmcia_socket *sock; + pccard_mem_map ctl; +} window_t; + /* Maximum number of IO windows per socket */ #define MAX_IO_WIN 2 @@ -146,7 +155,7 @@ struct pcmcia_socket { u_int Config; } irq; io_window_t io[MAX_IO_WIN]; - pccard_mem_map win[MAX_WIN]; + window_t win[MAX_WIN]; struct list_head cis_cache; size_t fake_cis_len; u8 *fake_cis; @@ -163,7 +172,7 @@ struct pcmcia_socket { u_int irq_mask; u_int map_size; u_int io_offset; - u_int pci_irq; + u_char pci_irq; struct pci_dev * cb_dev; diff --git a/trunk/kernel/capability.c b/trunk/kernel/capability.c index 7f876e60521f..4e17041963f5 100644 --- a/trunk/kernel/capability.c +++ b/trunk/kernel/capability.c @@ -29,6 +29,7 @@ EXPORT_SYMBOL(__cap_empty_set); EXPORT_SYMBOL(__cap_full_set); EXPORT_SYMBOL(__cap_init_eff_set); +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES int file_caps_enabled = 1; static int __init file_caps_disable(char *str) @@ -37,6 +38,7 @@ static int __init file_caps_disable(char *str) return 1; } __setup("no_file_caps", file_caps_disable); +#endif /* * More recent versions of libcap are available from: @@ -167,8 +169,8 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) kernel_cap_t pE, pI, pP; ret = cap_validate_magic(header, &tocopy); - if ((dataptr == NULL) || (ret != 0)) - return ((dataptr == NULL) && (ret == -EINVAL)) ? 0 : ret; + if (ret != 0) + return ret; if (get_user(pid, &header->pid)) return -EFAULT; @@ -236,7 +238,7 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) { struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; - unsigned i, tocopy, copybytes; + unsigned i, tocopy; kernel_cap_t inheritable, permitted, effective; struct cred *new; int ret; @@ -253,11 +255,8 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) if (pid != 0 && pid != task_pid_vnr(current)) return -EPERM; - copybytes = tocopy * sizeof(struct __user_cap_data_struct); - if (copybytes > sizeof(kdata)) - return -EFAULT; - - if (copy_from_user(&kdata, data, copybytes)) + if (copy_from_user(&kdata, data, + tocopy * sizeof(struct __user_cap_data_struct))) return -EFAULT; for (i = 0; i < tocopy; i++) { diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 25b103190364..9fcb53a11f87 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -80,16 +80,16 @@ int __request_module(bool wait, const char *fmt, ...) #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ static int kmod_loop_msg; + ret = security_kernel_module_request(); + if (ret) + return ret; + va_start(args, fmt); ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); va_end(args); if (ret >= MODULE_NAME_LEN) return -ENAMETOOLONG; - ret = security_kernel_module_request(module_name); - if (ret) - return ret; - /* If modprobe needs a service that is in a module, we get a recursive * loop. Limit the number of running kmod threads to max_threads/2 or * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 292ddc3cef9c..73f5e4b64010 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1058,6 +1059,9 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, } error = security_file_mmap(file, reqprot, prot, flags, addr, 0); + if (error) + return error; + error = ima_file_mmap(file, prot); if (error) return error; diff --git a/trunk/scripts/selinux/Makefile b/trunk/scripts/selinux/Makefile index e8049da1831f..ca4b1ec01822 100644 --- a/trunk/scripts/selinux/Makefile +++ b/trunk/scripts/selinux/Makefile @@ -1,2 +1,2 @@ -subdir-y := mdp genheaders -subdir- += mdp genheaders +subdir-y := mdp +subdir- += mdp diff --git a/trunk/scripts/selinux/genheaders/.gitignore b/trunk/scripts/selinux/genheaders/.gitignore deleted file mode 100644 index 4c0b646ff8d5..000000000000 --- a/trunk/scripts/selinux/genheaders/.gitignore +++ /dev/null @@ -1 +0,0 @@ -genheaders diff --git a/trunk/scripts/selinux/genheaders/Makefile b/trunk/scripts/selinux/genheaders/Makefile deleted file mode 100644 index 417b165008ee..000000000000 --- a/trunk/scripts/selinux/genheaders/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -hostprogs-y := genheaders -HOST_EXTRACFLAGS += -Isecurity/selinux/include - -always := $(hostprogs-y) -clean-files := $(hostprogs-y) diff --git a/trunk/scripts/selinux/genheaders/genheaders.c b/trunk/scripts/selinux/genheaders/genheaders.c deleted file mode 100644 index 24626968055d..000000000000 --- a/trunk/scripts/selinux/genheaders/genheaders.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include -#include -#include -#include - -struct security_class_mapping { - const char *name; - const char *perms[sizeof(unsigned) * 8 + 1]; -}; - -#include "classmap.h" -#include "initial_sid_to_string.h" - -#define max(x, y) (((int)(x) > (int)(y)) ? x : y) - -const char *progname; - -static void usage(void) -{ - printf("usage: %s flask.h av_permissions.h\n", progname); - exit(1); -} - -static char *stoupperx(const char *s) -{ - char *s2 = strdup(s); - char *p; - - if (!s2) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(3); - } - - for (p = s2; *p; p++) - *p = toupper(*p); - return s2; -} - -int main(int argc, char *argv[]) -{ - int i, j, k; - int isids_len; - FILE *fout; - - progname = argv[0]; - - if (argc < 3) - usage(); - - fout = fopen(argv[1], "w"); - if (!fout) { - fprintf(stderr, "Could not open %s for writing: %s\n", - argv[1], strerror(errno)); - exit(2); - } - - for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; - map->name = stoupperx(map->name); - for (j = 0; map->perms[j]; j++) - map->perms[j] = stoupperx(map->perms[j]); - } - - isids_len = sizeof(initial_sid_to_string) / sizeof (char *); - for (i = 1; i < isids_len; i++) - initial_sid_to_string[i] = stoupperx(initial_sid_to_string[i]); - - fprintf(fout, "/* This file is automatically generated. Do not edit. */\n"); - fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n"); - - for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; - fprintf(fout, "#define SECCLASS_%s", map->name); - for (j = 0; j < max(1, 40 - strlen(map->name)); j++) - fprintf(fout, " "); - fprintf(fout, "%2d\n", i+1); - } - - fprintf(fout, "\n"); - - for (i = 1; i < isids_len; i++) { - char *s = initial_sid_to_string[i]; - fprintf(fout, "#define SECINITSID_%s", s); - for (j = 0; j < max(1, 40 - strlen(s)); j++) - fprintf(fout, " "); - fprintf(fout, "%2d\n", i); - } - fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1); - fprintf(fout, "\n#endif\n"); - fclose(fout); - - fout = fopen(argv[2], "w"); - if (!fout) { - fprintf(stderr, "Could not open %s for writing: %s\n", - argv[2], strerror(errno)); - exit(4); - } - - fprintf(fout, "/* This file is automatically generated. Do not edit. */\n"); - fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n"); - - for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; - for (j = 0; map->perms[j]; j++) { - fprintf(fout, "#define %s__%s", map->name, - map->perms[j]); - for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++) - fprintf(fout, " "); - fprintf(fout, "0x%08xUL\n", (1< #include +#include "flask.h" + static void usage(char *name) { printf("usage: %s [-m] policy_file context_file\n", name); exit(1); } -/* Class/perm mapping support */ -struct security_class_mapping { - const char *name; - const char *perms[sizeof(unsigned) * 8 + 1]; +static void find_common_name(char *cname, char *dest, int len) +{ + char *start, *end; + + start = strchr(cname, '_')+1; + end = strchr(start, '_'); + if (!start || !end || start-cname > len || end-start > len) { + printf("Error with commons defines\n"); + exit(1); + } + strncpy(dest, start, end-start); + dest[end-start] = '\0'; +} + +#define S_(x) x, +static char *classlist[] = { +#include "class_to_string.h" + NULL }; +#undef S_ -#include "classmap.h" #include "initial_sid_to_string.h" +#define TB_(x) char *x[] = { +#define TE_(x) NULL }; +#define S_(x) x, +#include "common_perm_to_string.h" +#undef TB_ +#undef TE_ +#undef S_ + +struct common { + char *cname; + char **perms; +}; +struct common common[] = { +#define TB_(x) { #x, x }, +#define S_(x) +#define TE_(x) +#include "common_perm_to_string.h" +#undef TB_ +#undef TE_ +#undef S_ +}; + +#define S_(x, y, z) {x, #y}, +struct av_inherit { + int class; + char *common; +}; +struct av_inherit av_inherit[] = { +#include "av_inherit.h" +}; +#undef S_ + +#include "av_permissions.h" +#define S_(x, y, z) {x, y, z}, +struct av_perms { + int class; + int perm_i; + char *perm_s; +}; +struct av_perms av_perms[] = { +#include "av_perm_to_string.h" +}; +#undef S_ + int main(int argc, char *argv[]) { int i, j, mls = 0; - int initial_sid_to_string_len; char **arg, *polout, *ctxout; - + int classlist_len, initial_sid_to_string_len; FILE *fout; if (argc < 3) @@ -68,28 +127,67 @@ int main(int argc, char *argv[]) usage(argv[0]); } + classlist_len = sizeof(classlist) / sizeof(char *); /* print out the classes */ - for (i = 0; secclass_map[i].name; i++) - fprintf(fout, "class %s\n", secclass_map[i].name); + for (i=1; i < classlist_len; i++) { + if(classlist[i]) + fprintf(fout, "class %s\n", classlist[i]); + else + fprintf(fout, "class user%d\n", i); + } fprintf(fout, "\n"); initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); /* print out the sids */ - for (i = 1; i < initial_sid_to_string_len; i++) + for (i=1; i < initial_sid_to_string_len; i++) fprintf(fout, "sid %s\n", initial_sid_to_string[i]); fprintf(fout, "\n"); - /* print out the class permissions */ - for (i = 0; secclass_map[i].name; i++) { - struct security_class_mapping *map = &secclass_map[i]; - fprintf(fout, "class %s\n", map->name); - fprintf(fout, "{\n"); - for (j = 0; map->perms[j]; j++) - fprintf(fout, "\t%s\n", map->perms[j]); + /* print out the commons */ + for (i=0; i< sizeof(common)/sizeof(struct common); i++) { + char cname[101]; + find_common_name(common[i].cname, cname, 100); + cname[100] = '\0'; + fprintf(fout, "common %s\n{\n", cname); + for (j=0; common[i].perms[j]; j++) + fprintf(fout, "\t%s\n", common[i].perms[j]); fprintf(fout, "}\n\n"); } fprintf(fout, "\n"); + /* print out the class permissions */ + for (i=1; i < classlist_len; i++) { + if (classlist[i]) { + int firstperm = -1, numperms = 0; + + fprintf(fout, "class %s\n", classlist[i]); + /* does it inherit from a common? */ + for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++) + if (av_inherit[j].class == i) + fprintf(fout, "inherits %s\n", av_inherit[j].common); + + for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) { + if (av_perms[j].class == i) { + if (firstperm == -1) + firstperm = j; + numperms++; + } + } + if (!numperms) { + fprintf(fout, "\n"); + continue; + } + + fprintf(fout, "{\n"); + /* print out the av_perms */ + for (j=0; j < numperms; j++) { + fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s); + } + fprintf(fout, "}\n\n"); + } + } + fprintf(fout, "\n"); + /* NOW PRINT OUT MLS STUFF */ if (mls) { printf("MLS not yet implemented\n"); @@ -99,34 +197,31 @@ int main(int argc, char *argv[]) /* types, roles, and allows */ fprintf(fout, "type base_t;\n"); fprintf(fout, "role base_r types { base_t };\n"); - for (i = 0; secclass_map[i].name; i++) - fprintf(fout, "allow base_t base_t:%s *;\n", - secclass_map[i].name); + for (i=1; i < classlist_len; i++) { + if (classlist[i]) + fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]); + else + fprintf(fout, "allow base_t base_t:user%d *;\n", i); + } fprintf(fout, "user user_u roles { base_r };\n"); fprintf(fout, "\n"); /* default sids */ - for (i = 1; i < initial_sid_to_string_len; i++) + for (i=1; i < initial_sid_to_string_len; i++) fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); fprintf(fout, "\n"); + fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr lustre user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n"); fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n"); diff --git a/trunk/security/Kconfig b/trunk/security/Kconfig index 226b9556b25f..fb363cd81cf6 100644 --- a/trunk/security/Kconfig +++ b/trunk/security/Kconfig @@ -91,6 +91,28 @@ config SECURITY_PATH implement pathname based access controls. If you are unsure how to answer this question, answer N. +config SECURITY_FILE_CAPABILITIES + bool "File POSIX Capabilities" + default n + help + This enables filesystem capabilities, allowing you to give + binaries a subset of root's powers without using setuid 0. + + If in doubt, answer N. + +config SECURITY_ROOTPLUG + bool "Root Plug Support" + depends on USB=y && SECURITY + help + This is a sample LSM module that should only be used as such. + It prevents any programs running with egid == 0 if a specific + USB device is not present in the system. + + See for + more information about this module. + + If you are unsure how to answer this question, answer N. + config INTEL_TXT bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)" depends on HAVE_INTEL_TXT @@ -143,37 +165,5 @@ source security/tomoyo/Kconfig source security/integrity/ima/Kconfig -choice - prompt "Default security module" - default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX - default DEFAULT_SECURITY_SMACK if SECURITY_SMACK - default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO - default DEFAULT_SECURITY_DAC - - help - Select the security module that will be used by default if the - kernel parameter security= is not specified. - - config DEFAULT_SECURITY_SELINUX - bool "SELinux" if SECURITY_SELINUX=y - - config DEFAULT_SECURITY_SMACK - bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y - - config DEFAULT_SECURITY_TOMOYO - bool "TOMOYO" if SECURITY_TOMOYO=y - - config DEFAULT_SECURITY_DAC - bool "Unix Discretionary Access Controls" - -endchoice - -config DEFAULT_SECURITY - string - default "selinux" if DEFAULT_SECURITY_SELINUX - default "smack" if DEFAULT_SECURITY_SMACK - default "tomoyo" if DEFAULT_SECURITY_TOMOYO - default "" if DEFAULT_SECURITY_DAC - endmenu diff --git a/trunk/security/Makefile b/trunk/security/Makefile index bb44e350c618..95ecc06392d7 100644 --- a/trunk/security/Makefile +++ b/trunk/security/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o obj-$(CONFIG_AUDIT) += lsm_audit.o obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o +obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o # Object integrity file lists diff --git a/trunk/security/capability.c b/trunk/security/capability.c index 5c700e1a4fd3..fce07a7bc825 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -308,22 +308,6 @@ static int cap_path_truncate(struct path *path, loff_t length, { return 0; } - -static int cap_path_chmod(struct dentry *dentry, struct vfsmount *mnt, - mode_t mode) -{ - return 0; -} - -static int cap_path_chown(struct path *path, uid_t uid, gid_t gid) -{ - return 0; -} - -static int cap_path_chroot(struct path *root) -{ - return 0; -} #endif static int cap_file_permission(struct file *file, int mask) @@ -421,7 +405,7 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode) return 0; } -static int cap_kernel_module_request(char *kmod_name) +static int cap_kernel_module_request(void) { return 0; } @@ -993,9 +977,6 @@ void security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, path_link); set_to_cap_if_null(ops, path_rename); set_to_cap_if_null(ops, path_truncate); - set_to_cap_if_null(ops, path_chmod); - set_to_cap_if_null(ops, path_chown); - set_to_cap_if_null(ops, path_chroot); #endif set_to_cap_if_null(ops, file_permission); set_to_cap_if_null(ops, file_alloc_security); diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index f800fdb3de94..fe30751a6cd9 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -1,4 +1,4 @@ -/* Common capabilities, needed by capability.o. +/* Common capabilities, needed by capability.o and root_plug.o * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -173,6 +173,7 @@ int cap_capget(struct task_struct *target, kernel_cap_t *effective, */ static inline int cap_inh_is_capped(void) { +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES /* they are so limited unless the current task has the CAP_SETPCAP * capability @@ -180,6 +181,7 @@ static inline int cap_inh_is_capped(void) if (cap_capable(current, current_cred(), CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0) return 0; +#endif return 1; } @@ -237,6 +239,8 @@ static inline void bprm_clear_caps(struct linux_binprm *bprm) bprm->cap_effective = false; } +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES + /** * cap_inode_need_killpriv - Determine if inode change affects privileges * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV @@ -417,6 +421,49 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective) return rc; } +#else +int cap_inode_need_killpriv(struct dentry *dentry) +{ + return 0; +} + +int cap_inode_killpriv(struct dentry *dentry) +{ + return 0; +} + +int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps) +{ + memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data)); + return -ENODATA; +} + +static inline int get_file_caps(struct linux_binprm *bprm, bool *effective) +{ + bprm_clear_caps(bprm); + return 0; +} +#endif + +/* + * Determine whether a exec'ing process's new permitted capabilities should be + * limited to just what it already has. + * + * This prevents processes that are being ptraced from gaining access to + * CAP_SETPCAP, unless the process they're tracing already has it, and the + * binary they're executing has filecaps that elevate it. + * + * Returns 1 if they should be limited, 0 if they are not. + */ +static inline int cap_limit_ptraced_target(void) +{ +#ifndef CONFIG_SECURITY_FILE_CAPABILITIES + if (capable(CAP_SETPCAP)) + return 0; +#endif + return 1; +} + /** * cap_bprm_set_creds - Set up the proposed credentials for execve(). * @bprm: The execution parameters, including the proposed creds @@ -476,8 +523,9 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) new->euid = new->uid; new->egid = new->gid; } - new->cap_permitted = cap_intersect(new->cap_permitted, - old->cap_permitted); + if (cap_limit_ptraced_target()) + new->cap_permitted = cap_intersect(new->cap_permitted, + old->cap_permitted); } new->suid = new->fsuid = new->euid; @@ -691,6 +739,7 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags) return 0; } +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES /* * Rationale: code calling task_setscheduler, task_setioprio, and * task_setnice, assumes that @@ -771,6 +820,22 @@ static long cap_prctl_drop(struct cred *new, unsigned long cap) return 0; } +#else +int cap_task_setscheduler (struct task_struct *p, int policy, + struct sched_param *lp) +{ + return 0; +} +int cap_task_setioprio (struct task_struct *p, int ioprio) +{ + return 0; +} +int cap_task_setnice (struct task_struct *p, int nice) +{ + return 0; +} +#endif + /** * cap_task_prctl - Implement process control functions for this security module * @option: The process control function requested @@ -801,6 +866,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, error = !!cap_raised(new->cap_bset, arg2); goto no_change; +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES case PR_CAPBSET_DROP: error = cap_prctl_drop(new, arg2); if (error < 0) @@ -851,6 +917,8 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, error = new->securebits; goto no_change; +#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ + case PR_GET_KEEPCAPS: if (issecure(SECURE_KEEP_CAPS)) error = 1; diff --git a/trunk/security/integrity/ima/Kconfig b/trunk/security/integrity/ima/Kconfig index 3d7846de8069..53d9764e8f09 100644 --- a/trunk/security/integrity/ima/Kconfig +++ b/trunk/security/integrity/ima/Kconfig @@ -3,7 +3,6 @@ config IMA bool "Integrity Measurement Architecture(IMA)" depends on ACPI - depends on SECURITY select SECURITYFS select CRYPTO select CRYPTO_HMAC diff --git a/trunk/security/lsm_audit.c b/trunk/security/lsm_audit.c index 51bd0fd9c9f0..3bb90b6f1dd3 100644 --- a/trunk/security/lsm_audit.c +++ b/trunk/security/lsm_audit.c @@ -354,10 +354,6 @@ static void dump_common_audit_data(struct audit_buffer *ab, } break; #endif - case LSM_AUDIT_DATA_KMOD: - audit_log_format(ab, " kmod="); - audit_log_untrustedstring(ab, a->u.kmod_name); - break; } /* switch (a->type) */ } diff --git a/trunk/security/min_addr.c b/trunk/security/min_addr.c index fc43c9d37084..c844eed7915d 100644 --- a/trunk/security/min_addr.c +++ b/trunk/security/min_addr.c @@ -33,9 +33,6 @@ int mmap_min_addr_handler(struct ctl_table *table, int write, { int ret; - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); update_mmap_min_addr(); diff --git a/trunk/security/root_plug.c b/trunk/security/root_plug.c new file mode 100644 index 000000000000..2f7ffa67c4d2 --- /dev/null +++ b/trunk/security/root_plug.c @@ -0,0 +1,90 @@ +/* + * Root Plug sample LSM module + * + * Originally written for a Linux Journal. + * + * Copyright (C) 2002 Greg Kroah-Hartman + * + * Prevents any programs running with egid == 0 if a specific USB device + * is not present in the system. Yes, it can be gotten around, but is a + * nice starting point for people to play with, and learn the LSM + * interface. + * + * If you want to turn this into something with a semblance of security, + * you need to hook the task_* functions also. + * + * See http://www.linuxjournal.com/article.php?sid=6279 for more information + * about this code. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#include +#include +#include +#include +#include + +/* default is a generic type of usb to serial converter */ +static int vendor_id = 0x0557; +static int product_id = 0x2008; + +module_param(vendor_id, uint, 0400); +module_param(product_id, uint, 0400); + +/* should we print out debug messages */ +static int debug = 0; + +module_param(debug, bool, 0600); + +#define MY_NAME "root_plug" + +#define root_dbg(fmt, arg...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "%s: %s: " fmt , \ + MY_NAME , __func__ , \ + ## arg); \ + } while (0) + +static int rootplug_bprm_check_security (struct linux_binprm *bprm) +{ + struct usb_device *dev; + + root_dbg("file %s, e_uid = %d, e_gid = %d\n", + bprm->filename, bprm->cred->euid, bprm->cred->egid); + + if (bprm->cred->egid == 0) { + dev = usb_find_device(vendor_id, product_id); + if (!dev) { + root_dbg("e_gid = 0, and device not found, " + "task not allowed to run...\n"); + return -EPERM; + } + usb_put_dev(dev); + } + + return 0; +} + +static struct security_operations rootplug_security_ops = { + .bprm_check_security = rootplug_bprm_check_security, +}; + +static int __init rootplug_init (void) +{ + /* register ourselves with the security framework */ + if (register_security (&rootplug_security_ops)) { + printk (KERN_INFO + "Failure registering Root Plug module with the kernel\n"); + return -EINVAL; + } + printk (KERN_INFO "Root Plug module initialized, " + "vendor_id = %4.4x, product id = %4.4x\n", vendor_id, product_id); + return 0; +} + +security_initcall (rootplug_init); diff --git a/trunk/security/security.c b/trunk/security/security.c index 24e060be9fa5..c4c673240c1c 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -16,11 +16,9 @@ #include #include #include -#include /* Boot-time LSM user choice */ -static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = - CONFIG_DEFAULT_SECURITY; +static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1]; /* things that live in capability.c */ extern struct security_operations default_security_ops; @@ -81,10 +79,8 @@ __setup("security=", choose_lsm); * * Return true if: * -The passed LSM is the one chosen by user at boot time, - * -or the passed LSM is configured as the default and the user did not - * choose an alternate LSM at boot time, - * -or there is no default LSM set and the user didn't specify a - * specific LSM and we're the first to ask for registration permission, + * -or user didn't specify a specific LSM and we're the first to ask + * for registration permission, * -or the passed LSM is currently loaded. * Otherwise, return false. */ @@ -239,12 +235,7 @@ int security_bprm_set_creds(struct linux_binprm *bprm) int security_bprm_check(struct linux_binprm *bprm) { - int ret; - - ret = security_ops->bprm_check_security(bprm); - if (ret) - return ret; - return ima_bprm_check(bprm); + return security_ops->bprm_check_security(bprm); } void security_bprm_committing_creds(struct linux_binprm *bprm) @@ -361,21 +352,12 @@ EXPORT_SYMBOL(security_sb_parse_opts_str); int security_inode_alloc(struct inode *inode) { - int ret; - inode->i_security = NULL; - ret = security_ops->inode_alloc_security(inode); - if (ret) - return ret; - ret = ima_inode_alloc(inode); - if (ret) - security_inode_free(inode); - return ret; + return security_ops->inode_alloc_security(inode); } void security_inode_free(struct inode *inode) { - ima_inode_free(inode); security_ops->inode_free_security(inode); } @@ -452,26 +434,6 @@ int security_path_truncate(struct path *path, loff_t length, return 0; return security_ops->path_truncate(path, length, time_attrs); } - -int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt, - mode_t mode) -{ - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; - return security_ops->path_chmod(dentry, mnt, mode); -} - -int security_path_chown(struct path *path, uid_t uid, gid_t gid) -{ - if (unlikely(IS_PRIVATE(path->dentry->d_inode))) - return 0; - return security_ops->path_chown(path, uid, gid); -} - -int security_path_chroot(struct path *path) -{ - return security_ops->path_chroot(path); -} #endif int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) @@ -666,8 +628,6 @@ int security_file_alloc(struct file *file) void security_file_free(struct file *file) { security_ops->file_free_security(file); - if (file->f_dentry) - ima_file_free(file); } int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -679,12 +639,7 @@ int security_file_mmap(struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags, unsigned long addr, unsigned long addr_only) { - int ret; - - ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only); - if (ret) - return ret; - return ima_file_mmap(file, prot); + return security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only); } int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, @@ -764,9 +719,9 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode) return security_ops->kernel_create_files_as(new, inode); } -int security_kernel_module_request(char *kmod_name) +int security_kernel_module_request(void) { - return security_ops->kernel_module_request(kmod_name); + return security_ops->kernel_module_request(); } int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) diff --git a/trunk/security/selinux/.gitignore b/trunk/security/selinux/.gitignore deleted file mode 100644 index 2e5040a3d48b..000000000000 --- a/trunk/security/selinux/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -av_permissions.h -flask.h diff --git a/trunk/security/selinux/Makefile b/trunk/security/selinux/Makefile index f013982df417..d47fc5e545e0 100644 --- a/trunk/security/selinux/Makefile +++ b/trunk/security/selinux/Makefile @@ -18,13 +18,5 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o selinux-$(CONFIG_NETLABEL) += netlabel.o -EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include +EXTRA_CFLAGS += -Isecurity/selinux/include -$(obj)/avc.o: $(obj)/flask.h - -quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h - cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h - -targets += flask.h -$(obj)/flask.h: $(src)/include/classmap.h FORCE - $(call if_changed,flask) diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index f2dde268165a..b4b5da1c0a42 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -31,7 +31,43 @@ #include #include "avc.h" #include "avc_ss.h" -#include "classmap.h" + +static const struct av_perm_to_string av_perm_to_string[] = { +#define S_(c, v, s) { c, v, s }, +#include "av_perm_to_string.h" +#undef S_ +}; + +static const char *class_to_string[] = { +#define S_(s) s, +#include "class_to_string.h" +#undef S_ +}; + +#define TB_(s) static const char *s[] = { +#define TE_(s) }; +#define S_(s) s, +#include "common_perm_to_string.h" +#undef TB_ +#undef TE_ +#undef S_ + +static const struct av_inherit av_inherit[] = { +#define S_(c, i, b) { .tclass = c,\ + .common_pts = common_##i##_perm_to_string,\ + .common_base = b }, +#include "av_inherit.h" +#undef S_ +}; + +const struct selinux_class_perm selinux_class_perm = { + .av_perm_to_string = av_perm_to_string, + .av_pts_len = ARRAY_SIZE(av_perm_to_string), + .class_to_string = class_to_string, + .cts_len = ARRAY_SIZE(class_to_string), + .av_inherit = av_inherit, + .av_inherit_len = ARRAY_SIZE(av_inherit) +}; #define AVC_CACHE_SLOTS 512 #define AVC_DEF_CACHE_THRESHOLD 512 @@ -103,28 +139,52 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) */ static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av) { - const char **perms; - int i, perm; + const char **common_pts = NULL; + u32 common_base = 0; + int i, i2, perm; if (av == 0) { audit_log_format(ab, " null"); return; } - perms = secclass_map[tclass-1].perms; + for (i = 0; i < ARRAY_SIZE(av_inherit); i++) { + if (av_inherit[i].tclass == tclass) { + common_pts = av_inherit[i].common_pts; + common_base = av_inherit[i].common_base; + break; + } + } audit_log_format(ab, " {"); i = 0; perm = 1; - while (i < (sizeof(av) * 8)) { - if ((perm & av) && perms[i]) { - audit_log_format(ab, " %s", perms[i]); + while (perm < common_base) { + if (perm & av) { + audit_log_format(ab, " %s", common_pts[i]); av &= ~perm; } i++; perm <<= 1; } + while (i < sizeof(av) * 8) { + if (perm & av) { + for (i2 = 0; i2 < ARRAY_SIZE(av_perm_to_string); i2++) { + if ((av_perm_to_string[i2].tclass == tclass) && + (av_perm_to_string[i2].value == perm)) + break; + } + if (i2 < ARRAY_SIZE(av_perm_to_string)) { + audit_log_format(ab, " %s", + av_perm_to_string[i2].name); + av &= ~perm; + } + } + i++; + perm <<= 1; + } + if (av) audit_log_format(ab, " 0x%x", av); @@ -159,8 +219,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla kfree(scontext); } - BUG_ON(tclass >= ARRAY_SIZE(secclass_map)); - audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name); + BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]); + audit_log_format(ab, " tclass=%s", class_to_string[tclass]); } /** diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index c96d63ec4753..bb230d5d7085 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -91,6 +91,7 @@ #define NUM_SEL_MNT_OPTS 5 +extern unsigned int policydb_loaded_version; extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); extern struct security_operations *security_ops; @@ -3337,18 +3338,9 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) return 0; } -static int selinux_kernel_module_request(char *kmod_name) +static int selinux_kernel_module_request(void) { - u32 sid; - struct common_audit_data ad; - - sid = task_sid(current); - - COMMON_AUDIT_DATA_INIT(&ad, KMOD); - ad.u.kmod_name = kmod_name; - - return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, - SYSTEM__MODULE_REQUEST, &ad); + return task_has_system(current, SYSTEM__MODULE_REQUEST); } static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) @@ -4722,7 +4714,10 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) if (err) return err; - return selinux_nlmsg_perm(sk, skb); + if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS) + err = selinux_nlmsg_perm(sk, skb); + + return err; } static int selinux_netlink_recv(struct sk_buff *skb, int capability) @@ -5835,12 +5830,12 @@ int selinux_disable(void) selinux_disabled = 1; selinux_enabled = 0; - /* Reset security_ops to the secondary module, dummy or capability. */ - security_ops = secondary_ops; - /* Try to destroy the avc node cache */ avc_disable(); + /* Reset security_ops to the secondary module, dummy or capability. */ + security_ops = secondary_ops; + /* Unregister netfilter hooks. */ selinux_nf_ip_exit(); diff --git a/trunk/security/selinux/include/av_inherit.h b/trunk/security/selinux/include/av_inherit.h new file mode 100644 index 000000000000..abedcd704dae --- /dev/null +++ b/trunk/security/selinux/include/av_inherit.h @@ -0,0 +1,34 @@ +/* This file is automatically generated. Do not edit. */ + S_(SECCLASS_DIR, file, 0x00020000UL) + S_(SECCLASS_FILE, file, 0x00020000UL) + S_(SECCLASS_LNK_FILE, file, 0x00020000UL) + S_(SECCLASS_CHR_FILE, file, 0x00020000UL) + S_(SECCLASS_BLK_FILE, file, 0x00020000UL) + S_(SECCLASS_SOCK_FILE, file, 0x00020000UL) + S_(SECCLASS_FIFO_FILE, file, 0x00020000UL) + S_(SECCLASS_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_TCP_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_UDP_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_RAWIP_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_PACKET_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_IPC, ipc, 0x00000200UL) + S_(SECCLASS_SEM, ipc, 0x00000200UL) + S_(SECCLASS_MSGQ, ipc, 0x00000200UL) + S_(SECCLASS_SHM, ipc, 0x00000200UL) + S_(SECCLASS_NETLINK_ROUTE_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_FIREWALL_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_NFLOG_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_XFRM_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_SELINUX_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_AUDIT_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_IP6FW_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_APPLETALK_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_DCCP_SOCKET, socket, 0x00400000UL) diff --git a/trunk/security/selinux/include/av_perm_to_string.h b/trunk/security/selinux/include/av_perm_to_string.h new file mode 100644 index 000000000000..2b683ad83d21 --- /dev/null +++ b/trunk/security/selinux/include/av_perm_to_string.h @@ -0,0 +1,183 @@ +/* This file is automatically generated. Do not edit. */ + S_(SECCLASS_FILESYSTEM, FILESYSTEM__MOUNT, "mount") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__REMOUNT, "remount") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__UNMOUNT, "unmount") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__GETATTR, "getattr") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, "relabelfrom") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, "relabelto") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__TRANSITION, "transition") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, "associate") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAMOD, "quotamod") + S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAGET, "quotaget") + S_(SECCLASS_DIR, DIR__ADD_NAME, "add_name") + S_(SECCLASS_DIR, DIR__REMOVE_NAME, "remove_name") + S_(SECCLASS_DIR, DIR__REPARENT, "reparent") + S_(SECCLASS_DIR, DIR__SEARCH, "search") + S_(SECCLASS_DIR, DIR__RMDIR, "rmdir") + S_(SECCLASS_DIR, DIR__OPEN, "open") + S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans") + S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint") + S_(SECCLASS_FILE, FILE__EXECMOD, "execmod") + S_(SECCLASS_FILE, FILE__OPEN, "open") + S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans") + S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint") + S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod") + S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open") + S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open") + S_(SECCLASS_SOCK_FILE, SOCK_FILE__OPEN, "open") + S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open") + S_(SECCLASS_FD, FD__USE, "use") + S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto") + S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn") + S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom") + S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind") + S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NAME_CONNECT, "name_connect") + S_(SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind") + S_(SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind") + S_(SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv") + S_(SECCLASS_NODE, NODE__TCP_SEND, "tcp_send") + S_(SECCLASS_NODE, NODE__UDP_RECV, "udp_recv") + S_(SECCLASS_NODE, NODE__UDP_SEND, "udp_send") + S_(SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv") + S_(SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send") + S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest") + S_(SECCLASS_NODE, NODE__DCCP_RECV, "dccp_recv") + S_(SECCLASS_NODE, NODE__DCCP_SEND, "dccp_send") + S_(SECCLASS_NODE, NODE__RECVFROM, "recvfrom") + S_(SECCLASS_NODE, NODE__SENDTO, "sendto") + S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv") + S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send") + S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv") + S_(SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send") + S_(SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv") + S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send") + S_(SECCLASS_NETIF, NETIF__DCCP_RECV, "dccp_recv") + S_(SECCLASS_NETIF, NETIF__DCCP_SEND, "dccp_send") + S_(SECCLASS_NETIF, NETIF__INGRESS, "ingress") + S_(SECCLASS_NETIF, NETIF__EGRESS, "egress") + S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto") + S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn") + S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom") + S_(SECCLASS_PROCESS, PROCESS__FORK, "fork") + S_(SECCLASS_PROCESS, PROCESS__TRANSITION, "transition") + S_(SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld") + S_(SECCLASS_PROCESS, PROCESS__SIGKILL, "sigkill") + S_(SECCLASS_PROCESS, PROCESS__SIGSTOP, "sigstop") + S_(SECCLASS_PROCESS, PROCESS__SIGNULL, "signull") + S_(SECCLASS_PROCESS, PROCESS__SIGNAL, "signal") + S_(SECCLASS_PROCESS, PROCESS__PTRACE, "ptrace") + S_(SECCLASS_PROCESS, PROCESS__GETSCHED, "getsched") + S_(SECCLASS_PROCESS, PROCESS__SETSCHED, "setsched") + S_(SECCLASS_PROCESS, PROCESS__GETSESSION, "getsession") + S_(SECCLASS_PROCESS, PROCESS__GETPGID, "getpgid") + S_(SECCLASS_PROCESS, PROCESS__SETPGID, "setpgid") + S_(SECCLASS_PROCESS, PROCESS__GETCAP, "getcap") + S_(SECCLASS_PROCESS, PROCESS__SETCAP, "setcap") + S_(SECCLASS_PROCESS, PROCESS__SHARE, "share") + S_(SECCLASS_PROCESS, PROCESS__GETATTR, "getattr") + S_(SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec") + S_(SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate") + S_(SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure") + S_(SECCLASS_PROCESS, PROCESS__SIGINH, "siginh") + S_(SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit") + S_(SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh") + S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition") + S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent") + S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem") + S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack") + S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap") + S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate") + S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate") + S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") + S_(SECCLASS_MSG, MSG__SEND, "send") + S_(SECCLASS_MSG, MSG__RECEIVE, "receive") + S_(SECCLASS_SHM, SHM__LOCK, "lock") + S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av") + S_(SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create") + S_(SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member") + S_(SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context") + S_(SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy") + S_(SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel") + S_(SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user") + S_(SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce") + S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool") + S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam") + S_(SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT, "setcheckreqprot") + S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info") + S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") + S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") + S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console") + S_(SECCLASS_SYSTEM, SYSTEM__MODULE_REQUEST, "module_request") + S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown") + S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override") + S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search") + S_(SECCLASS_CAPABILITY, CAPABILITY__FOWNER, "fowner") + S_(SECCLASS_CAPABILITY, CAPABILITY__FSETID, "fsetid") + S_(SECCLASS_CAPABILITY, CAPABILITY__KILL, "kill") + S_(SECCLASS_CAPABILITY, CAPABILITY__SETGID, "setgid") + S_(SECCLASS_CAPABILITY, CAPABILITY__SETUID, "setuid") + S_(SECCLASS_CAPABILITY, CAPABILITY__SETPCAP, "setpcap") + S_(SECCLASS_CAPABILITY, CAPABILITY__LINUX_IMMUTABLE, "linux_immutable") + S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BIND_SERVICE, "net_bind_service") + S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BROADCAST, "net_broadcast") + S_(SECCLASS_CAPABILITY, CAPABILITY__NET_ADMIN, "net_admin") + S_(SECCLASS_CAPABILITY, CAPABILITY__NET_RAW, "net_raw") + S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_LOCK, "ipc_lock") + S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_OWNER, "ipc_owner") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_MODULE, "sys_module") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RAWIO, "sys_rawio") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_CHROOT, "sys_chroot") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PTRACE, "sys_ptrace") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PACCT, "sys_pacct") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_ADMIN, "sys_admin") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_BOOT, "sys_boot") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_NICE, "sys_nice") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RESOURCE, "sys_resource") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TIME, "sys_time") + S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TTY_CONFIG, "sys_tty_config") + S_(SECCLASS_CAPABILITY, CAPABILITY__MKNOD, "mknod") + S_(SECCLASS_CAPABILITY, CAPABILITY__LEASE, "lease") + S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_WRITE, "audit_write") + S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_CONTROL, "audit_control") + S_(SECCLASS_CAPABILITY, CAPABILITY__SETFCAP, "setfcap") + S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_OVERRIDE, "mac_override") + S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_ADMIN, "mac_admin") + S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read") + S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write") + S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read") + S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write") + S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read") + S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write") + S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read") + S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write") + S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read") + S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write") + S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_RELAY, "nlmsg_relay") + S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV, "nlmsg_readpriv") + S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT, "nlmsg_tty_audit") + S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read") + S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write") + S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto") + S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom") + S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext") + S_(SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, "polmatch") + S_(SECCLASS_PACKET, PACKET__SEND, "send") + S_(SECCLASS_PACKET, PACKET__RECV, "recv") + S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") + S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in") + S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out") + S_(SECCLASS_PACKET, PACKET__FORWARD_IN, "forward_in") + S_(SECCLASS_PACKET, PACKET__FORWARD_OUT, "forward_out") + S_(SECCLASS_KEY, KEY__VIEW, "view") + S_(SECCLASS_KEY, KEY__READ, "read") + S_(SECCLASS_KEY, KEY__WRITE, "write") + S_(SECCLASS_KEY, KEY__SEARCH, "search") + S_(SECCLASS_KEY, KEY__LINK, "link") + S_(SECCLASS_KEY, KEY__SETATTR, "setattr") + S_(SECCLASS_KEY, KEY__CREATE, "create") + S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind") + S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect") + S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero") + S_(SECCLASS_PEER, PEER__RECV, "recv") + S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__USE_AS_OVERRIDE, "use_as_override") + S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__CREATE_FILES_AS, "create_files_as") diff --git a/trunk/security/selinux/include/av_permissions.h b/trunk/security/selinux/include/av_permissions.h new file mode 100644 index 000000000000..0546d616ccac --- /dev/null +++ b/trunk/security/selinux/include/av_permissions.h @@ -0,0 +1,870 @@ +/* This file is automatically generated. Do not edit. */ +#define COMMON_FILE__IOCTL 0x00000001UL +#define COMMON_FILE__READ 0x00000002UL +#define COMMON_FILE__WRITE 0x00000004UL +#define COMMON_FILE__CREATE 0x00000008UL +#define COMMON_FILE__GETATTR 0x00000010UL +#define COMMON_FILE__SETATTR 0x00000020UL +#define COMMON_FILE__LOCK 0x00000040UL +#define COMMON_FILE__RELABELFROM 0x00000080UL +#define COMMON_FILE__RELABELTO 0x00000100UL +#define COMMON_FILE__APPEND 0x00000200UL +#define COMMON_FILE__UNLINK 0x00000400UL +#define COMMON_FILE__LINK 0x00000800UL +#define COMMON_FILE__RENAME 0x00001000UL +#define COMMON_FILE__EXECUTE 0x00002000UL +#define COMMON_FILE__SWAPON 0x00004000UL +#define COMMON_FILE__QUOTAON 0x00008000UL +#define COMMON_FILE__MOUNTON 0x00010000UL +#define COMMON_SOCKET__IOCTL 0x00000001UL +#define COMMON_SOCKET__READ 0x00000002UL +#define COMMON_SOCKET__WRITE 0x00000004UL +#define COMMON_SOCKET__CREATE 0x00000008UL +#define COMMON_SOCKET__GETATTR 0x00000010UL +#define COMMON_SOCKET__SETATTR 0x00000020UL +#define COMMON_SOCKET__LOCK 0x00000040UL +#define COMMON_SOCKET__RELABELFROM 0x00000080UL +#define COMMON_SOCKET__RELABELTO 0x00000100UL +#define COMMON_SOCKET__APPEND 0x00000200UL +#define COMMON_SOCKET__BIND 0x00000400UL +#define COMMON_SOCKET__CONNECT 0x00000800UL +#define COMMON_SOCKET__LISTEN 0x00001000UL +#define COMMON_SOCKET__ACCEPT 0x00002000UL +#define COMMON_SOCKET__GETOPT 0x00004000UL +#define COMMON_SOCKET__SETOPT 0x00008000UL +#define COMMON_SOCKET__SHUTDOWN 0x00010000UL +#define COMMON_SOCKET__RECVFROM 0x00020000UL +#define COMMON_SOCKET__SENDTO 0x00040000UL +#define COMMON_SOCKET__RECV_MSG 0x00080000UL +#define COMMON_SOCKET__SEND_MSG 0x00100000UL +#define COMMON_SOCKET__NAME_BIND 0x00200000UL +#define COMMON_IPC__CREATE 0x00000001UL +#define COMMON_IPC__DESTROY 0x00000002UL +#define COMMON_IPC__GETATTR 0x00000004UL +#define COMMON_IPC__SETATTR 0x00000008UL +#define COMMON_IPC__READ 0x00000010UL +#define COMMON_IPC__WRITE 0x00000020UL +#define COMMON_IPC__ASSOCIATE 0x00000040UL +#define COMMON_IPC__UNIX_READ 0x00000080UL +#define COMMON_IPC__UNIX_WRITE 0x00000100UL +#define FILESYSTEM__MOUNT 0x00000001UL +#define FILESYSTEM__REMOUNT 0x00000002UL +#define FILESYSTEM__UNMOUNT 0x00000004UL +#define FILESYSTEM__GETATTR 0x00000008UL +#define FILESYSTEM__RELABELFROM 0x00000010UL +#define FILESYSTEM__RELABELTO 0x00000020UL +#define FILESYSTEM__TRANSITION 0x00000040UL +#define FILESYSTEM__ASSOCIATE 0x00000080UL +#define FILESYSTEM__QUOTAMOD 0x00000100UL +#define FILESYSTEM__QUOTAGET 0x00000200UL +#define DIR__IOCTL 0x00000001UL +#define DIR__READ 0x00000002UL +#define DIR__WRITE 0x00000004UL +#define DIR__CREATE 0x00000008UL +#define DIR__GETATTR 0x00000010UL +#define DIR__SETATTR 0x00000020UL +#define DIR__LOCK 0x00000040UL +#define DIR__RELABELFROM 0x00000080UL +#define DIR__RELABELTO 0x00000100UL +#define DIR__APPEND 0x00000200UL +#define DIR__UNLINK 0x00000400UL +#define DIR__LINK 0x00000800UL +#define DIR__RENAME 0x00001000UL +#define DIR__EXECUTE 0x00002000UL +#define DIR__SWAPON 0x00004000UL +#define DIR__QUOTAON 0x00008000UL +#define DIR__MOUNTON 0x00010000UL +#define DIR__ADD_NAME 0x00020000UL +#define DIR__REMOVE_NAME 0x00040000UL +#define DIR__REPARENT 0x00080000UL +#define DIR__SEARCH 0x00100000UL +#define DIR__RMDIR 0x00200000UL +#define DIR__OPEN 0x00400000UL +#define FILE__IOCTL 0x00000001UL +#define FILE__READ 0x00000002UL +#define FILE__WRITE 0x00000004UL +#define FILE__CREATE 0x00000008UL +#define FILE__GETATTR 0x00000010UL +#define FILE__SETATTR 0x00000020UL +#define FILE__LOCK 0x00000040UL +#define FILE__RELABELFROM 0x00000080UL +#define FILE__RELABELTO 0x00000100UL +#define FILE__APPEND 0x00000200UL +#define FILE__UNLINK 0x00000400UL +#define FILE__LINK 0x00000800UL +#define FILE__RENAME 0x00001000UL +#define FILE__EXECUTE 0x00002000UL +#define FILE__SWAPON 0x00004000UL +#define FILE__QUOTAON 0x00008000UL +#define FILE__MOUNTON 0x00010000UL +#define FILE__EXECUTE_NO_TRANS 0x00020000UL +#define FILE__ENTRYPOINT 0x00040000UL +#define FILE__EXECMOD 0x00080000UL +#define FILE__OPEN 0x00100000UL +#define LNK_FILE__IOCTL 0x00000001UL +#define LNK_FILE__READ 0x00000002UL +#define LNK_FILE__WRITE 0x00000004UL +#define LNK_FILE__CREATE 0x00000008UL +#define LNK_FILE__GETATTR 0x00000010UL +#define LNK_FILE__SETATTR 0x00000020UL +#define LNK_FILE__LOCK 0x00000040UL +#define LNK_FILE__RELABELFROM 0x00000080UL +#define LNK_FILE__RELABELTO 0x00000100UL +#define LNK_FILE__APPEND 0x00000200UL +#define LNK_FILE__UNLINK 0x00000400UL +#define LNK_FILE__LINK 0x00000800UL +#define LNK_FILE__RENAME 0x00001000UL +#define LNK_FILE__EXECUTE 0x00002000UL +#define LNK_FILE__SWAPON 0x00004000UL +#define LNK_FILE__QUOTAON 0x00008000UL +#define LNK_FILE__MOUNTON 0x00010000UL +#define CHR_FILE__IOCTL 0x00000001UL +#define CHR_FILE__READ 0x00000002UL +#define CHR_FILE__WRITE 0x00000004UL +#define CHR_FILE__CREATE 0x00000008UL +#define CHR_FILE__GETATTR 0x00000010UL +#define CHR_FILE__SETATTR 0x00000020UL +#define CHR_FILE__LOCK 0x00000040UL +#define CHR_FILE__RELABELFROM 0x00000080UL +#define CHR_FILE__RELABELTO 0x00000100UL +#define CHR_FILE__APPEND 0x00000200UL +#define CHR_FILE__UNLINK 0x00000400UL +#define CHR_FILE__LINK 0x00000800UL +#define CHR_FILE__RENAME 0x00001000UL +#define CHR_FILE__EXECUTE 0x00002000UL +#define CHR_FILE__SWAPON 0x00004000UL +#define CHR_FILE__QUOTAON 0x00008000UL +#define CHR_FILE__MOUNTON 0x00010000UL +#define CHR_FILE__EXECUTE_NO_TRANS 0x00020000UL +#define CHR_FILE__ENTRYPOINT 0x00040000UL +#define CHR_FILE__EXECMOD 0x00080000UL +#define CHR_FILE__OPEN 0x00100000UL +#define BLK_FILE__IOCTL 0x00000001UL +#define BLK_FILE__READ 0x00000002UL +#define BLK_FILE__WRITE 0x00000004UL +#define BLK_FILE__CREATE 0x00000008UL +#define BLK_FILE__GETATTR 0x00000010UL +#define BLK_FILE__SETATTR 0x00000020UL +#define BLK_FILE__LOCK 0x00000040UL +#define BLK_FILE__RELABELFROM 0x00000080UL +#define BLK_FILE__RELABELTO 0x00000100UL +#define BLK_FILE__APPEND 0x00000200UL +#define BLK_FILE__UNLINK 0x00000400UL +#define BLK_FILE__LINK 0x00000800UL +#define BLK_FILE__RENAME 0x00001000UL +#define BLK_FILE__EXECUTE 0x00002000UL +#define BLK_FILE__SWAPON 0x00004000UL +#define BLK_FILE__QUOTAON 0x00008000UL +#define BLK_FILE__MOUNTON 0x00010000UL +#define BLK_FILE__OPEN 0x00020000UL +#define SOCK_FILE__IOCTL 0x00000001UL +#define SOCK_FILE__READ 0x00000002UL +#define SOCK_FILE__WRITE 0x00000004UL +#define SOCK_FILE__CREATE 0x00000008UL +#define SOCK_FILE__GETATTR 0x00000010UL +#define SOCK_FILE__SETATTR 0x00000020UL +#define SOCK_FILE__LOCK 0x00000040UL +#define SOCK_FILE__RELABELFROM 0x00000080UL +#define SOCK_FILE__RELABELTO 0x00000100UL +#define SOCK_FILE__APPEND 0x00000200UL +#define SOCK_FILE__UNLINK 0x00000400UL +#define SOCK_FILE__LINK 0x00000800UL +#define SOCK_FILE__RENAME 0x00001000UL +#define SOCK_FILE__EXECUTE 0x00002000UL +#define SOCK_FILE__SWAPON 0x00004000UL +#define SOCK_FILE__QUOTAON 0x00008000UL +#define SOCK_FILE__MOUNTON 0x00010000UL +#define SOCK_FILE__OPEN 0x00020000UL +#define FIFO_FILE__IOCTL 0x00000001UL +#define FIFO_FILE__READ 0x00000002UL +#define FIFO_FILE__WRITE 0x00000004UL +#define FIFO_FILE__CREATE 0x00000008UL +#define FIFO_FILE__GETATTR 0x00000010UL +#define FIFO_FILE__SETATTR 0x00000020UL +#define FIFO_FILE__LOCK 0x00000040UL +#define FIFO_FILE__RELABELFROM 0x00000080UL +#define FIFO_FILE__RELABELTO 0x00000100UL +#define FIFO_FILE__APPEND 0x00000200UL +#define FIFO_FILE__UNLINK 0x00000400UL +#define FIFO_FILE__LINK 0x00000800UL +#define FIFO_FILE__RENAME 0x00001000UL +#define FIFO_FILE__EXECUTE 0x00002000UL +#define FIFO_FILE__SWAPON 0x00004000UL +#define FIFO_FILE__QUOTAON 0x00008000UL +#define FIFO_FILE__MOUNTON 0x00010000UL +#define FIFO_FILE__OPEN 0x00020000UL +#define FD__USE 0x00000001UL +#define SOCKET__IOCTL 0x00000001UL +#define SOCKET__READ 0x00000002UL +#define SOCKET__WRITE 0x00000004UL +#define SOCKET__CREATE 0x00000008UL +#define SOCKET__GETATTR 0x00000010UL +#define SOCKET__SETATTR 0x00000020UL +#define SOCKET__LOCK 0x00000040UL +#define SOCKET__RELABELFROM 0x00000080UL +#define SOCKET__RELABELTO 0x00000100UL +#define SOCKET__APPEND 0x00000200UL +#define SOCKET__BIND 0x00000400UL +#define SOCKET__CONNECT 0x00000800UL +#define SOCKET__LISTEN 0x00001000UL +#define SOCKET__ACCEPT 0x00002000UL +#define SOCKET__GETOPT 0x00004000UL +#define SOCKET__SETOPT 0x00008000UL +#define SOCKET__SHUTDOWN 0x00010000UL +#define SOCKET__RECVFROM 0x00020000UL +#define SOCKET__SENDTO 0x00040000UL +#define SOCKET__RECV_MSG 0x00080000UL +#define SOCKET__SEND_MSG 0x00100000UL +#define SOCKET__NAME_BIND 0x00200000UL +#define TCP_SOCKET__IOCTL 0x00000001UL +#define TCP_SOCKET__READ 0x00000002UL +#define TCP_SOCKET__WRITE 0x00000004UL +#define TCP_SOCKET__CREATE 0x00000008UL +#define TCP_SOCKET__GETATTR 0x00000010UL +#define TCP_SOCKET__SETATTR 0x00000020UL +#define TCP_SOCKET__LOCK 0x00000040UL +#define TCP_SOCKET__RELABELFROM 0x00000080UL +#define TCP_SOCKET__RELABELTO 0x00000100UL +#define TCP_SOCKET__APPEND 0x00000200UL +#define TCP_SOCKET__BIND 0x00000400UL +#define TCP_SOCKET__CONNECT 0x00000800UL +#define TCP_SOCKET__LISTEN 0x00001000UL +#define TCP_SOCKET__ACCEPT 0x00002000UL +#define TCP_SOCKET__GETOPT 0x00004000UL +#define TCP_SOCKET__SETOPT 0x00008000UL +#define TCP_SOCKET__SHUTDOWN 0x00010000UL +#define TCP_SOCKET__RECVFROM 0x00020000UL +#define TCP_SOCKET__SENDTO 0x00040000UL +#define TCP_SOCKET__RECV_MSG 0x00080000UL +#define TCP_SOCKET__SEND_MSG 0x00100000UL +#define TCP_SOCKET__NAME_BIND 0x00200000UL +#define TCP_SOCKET__CONNECTTO 0x00400000UL +#define TCP_SOCKET__NEWCONN 0x00800000UL +#define TCP_SOCKET__ACCEPTFROM 0x01000000UL +#define TCP_SOCKET__NODE_BIND 0x02000000UL +#define TCP_SOCKET__NAME_CONNECT 0x04000000UL +#define UDP_SOCKET__IOCTL 0x00000001UL +#define UDP_SOCKET__READ 0x00000002UL +#define UDP_SOCKET__WRITE 0x00000004UL +#define UDP_SOCKET__CREATE 0x00000008UL +#define UDP_SOCKET__GETATTR 0x00000010UL +#define UDP_SOCKET__SETATTR 0x00000020UL +#define UDP_SOCKET__LOCK 0x00000040UL +#define UDP_SOCKET__RELABELFROM 0x00000080UL +#define UDP_SOCKET__RELABELTO 0x00000100UL +#define UDP_SOCKET__APPEND 0x00000200UL +#define UDP_SOCKET__BIND 0x00000400UL +#define UDP_SOCKET__CONNECT 0x00000800UL +#define UDP_SOCKET__LISTEN 0x00001000UL +#define UDP_SOCKET__ACCEPT 0x00002000UL +#define UDP_SOCKET__GETOPT 0x00004000UL +#define UDP_SOCKET__SETOPT 0x00008000UL +#define UDP_SOCKET__SHUTDOWN 0x00010000UL +#define UDP_SOCKET__RECVFROM 0x00020000UL +#define UDP_SOCKET__SENDTO 0x00040000UL +#define UDP_SOCKET__RECV_MSG 0x00080000UL +#define UDP_SOCKET__SEND_MSG 0x00100000UL +#define UDP_SOCKET__NAME_BIND 0x00200000UL +#define UDP_SOCKET__NODE_BIND 0x00400000UL +#define RAWIP_SOCKET__IOCTL 0x00000001UL +#define RAWIP_SOCKET__READ 0x00000002UL +#define RAWIP_SOCKET__WRITE 0x00000004UL +#define RAWIP_SOCKET__CREATE 0x00000008UL +#define RAWIP_SOCKET__GETATTR 0x00000010UL +#define RAWIP_SOCKET__SETATTR 0x00000020UL +#define RAWIP_SOCKET__LOCK 0x00000040UL +#define RAWIP_SOCKET__RELABELFROM 0x00000080UL +#define RAWIP_SOCKET__RELABELTO 0x00000100UL +#define RAWIP_SOCKET__APPEND 0x00000200UL +#define RAWIP_SOCKET__BIND 0x00000400UL +#define RAWIP_SOCKET__CONNECT 0x00000800UL +#define RAWIP_SOCKET__LISTEN 0x00001000UL +#define RAWIP_SOCKET__ACCEPT 0x00002000UL +#define RAWIP_SOCKET__GETOPT 0x00004000UL +#define RAWIP_SOCKET__SETOPT 0x00008000UL +#define RAWIP_SOCKET__SHUTDOWN 0x00010000UL +#define RAWIP_SOCKET__RECVFROM 0x00020000UL +#define RAWIP_SOCKET__SENDTO 0x00040000UL +#define RAWIP_SOCKET__RECV_MSG 0x00080000UL +#define RAWIP_SOCKET__SEND_MSG 0x00100000UL +#define RAWIP_SOCKET__NAME_BIND 0x00200000UL +#define RAWIP_SOCKET__NODE_BIND 0x00400000UL +#define NODE__TCP_RECV 0x00000001UL +#define NODE__TCP_SEND 0x00000002UL +#define NODE__UDP_RECV 0x00000004UL +#define NODE__UDP_SEND 0x00000008UL +#define NODE__RAWIP_RECV 0x00000010UL +#define NODE__RAWIP_SEND 0x00000020UL +#define NODE__ENFORCE_DEST 0x00000040UL +#define NODE__DCCP_RECV 0x00000080UL +#define NODE__DCCP_SEND 0x00000100UL +#define NODE__RECVFROM 0x00000200UL +#define NODE__SENDTO 0x00000400UL +#define NETIF__TCP_RECV 0x00000001UL +#define NETIF__TCP_SEND 0x00000002UL +#define NETIF__UDP_RECV 0x00000004UL +#define NETIF__UDP_SEND 0x00000008UL +#define NETIF__RAWIP_RECV 0x00000010UL +#define NETIF__RAWIP_SEND 0x00000020UL +#define NETIF__DCCP_RECV 0x00000040UL +#define NETIF__DCCP_SEND 0x00000080UL +#define NETIF__INGRESS 0x00000100UL +#define NETIF__EGRESS 0x00000200UL +#define NETLINK_SOCKET__IOCTL 0x00000001UL +#define NETLINK_SOCKET__READ 0x00000002UL +#define NETLINK_SOCKET__WRITE 0x00000004UL +#define NETLINK_SOCKET__CREATE 0x00000008UL +#define NETLINK_SOCKET__GETATTR 0x00000010UL +#define NETLINK_SOCKET__SETATTR 0x00000020UL +#define NETLINK_SOCKET__LOCK 0x00000040UL +#define NETLINK_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_SOCKET__APPEND 0x00000200UL +#define NETLINK_SOCKET__BIND 0x00000400UL +#define NETLINK_SOCKET__CONNECT 0x00000800UL +#define NETLINK_SOCKET__LISTEN 0x00001000UL +#define NETLINK_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_SOCKET__GETOPT 0x00004000UL +#define NETLINK_SOCKET__SETOPT 0x00008000UL +#define NETLINK_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_SOCKET__SENDTO 0x00040000UL +#define NETLINK_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_SOCKET__NAME_BIND 0x00200000UL +#define PACKET_SOCKET__IOCTL 0x00000001UL +#define PACKET_SOCKET__READ 0x00000002UL +#define PACKET_SOCKET__WRITE 0x00000004UL +#define PACKET_SOCKET__CREATE 0x00000008UL +#define PACKET_SOCKET__GETATTR 0x00000010UL +#define PACKET_SOCKET__SETATTR 0x00000020UL +#define PACKET_SOCKET__LOCK 0x00000040UL +#define PACKET_SOCKET__RELABELFROM 0x00000080UL +#define PACKET_SOCKET__RELABELTO 0x00000100UL +#define PACKET_SOCKET__APPEND 0x00000200UL +#define PACKET_SOCKET__BIND 0x00000400UL +#define PACKET_SOCKET__CONNECT 0x00000800UL +#define PACKET_SOCKET__LISTEN 0x00001000UL +#define PACKET_SOCKET__ACCEPT 0x00002000UL +#define PACKET_SOCKET__GETOPT 0x00004000UL +#define PACKET_SOCKET__SETOPT 0x00008000UL +#define PACKET_SOCKET__SHUTDOWN 0x00010000UL +#define PACKET_SOCKET__RECVFROM 0x00020000UL +#define PACKET_SOCKET__SENDTO 0x00040000UL +#define PACKET_SOCKET__RECV_MSG 0x00080000UL +#define PACKET_SOCKET__SEND_MSG 0x00100000UL +#define PACKET_SOCKET__NAME_BIND 0x00200000UL +#define KEY_SOCKET__IOCTL 0x00000001UL +#define KEY_SOCKET__READ 0x00000002UL +#define KEY_SOCKET__WRITE 0x00000004UL +#define KEY_SOCKET__CREATE 0x00000008UL +#define KEY_SOCKET__GETATTR 0x00000010UL +#define KEY_SOCKET__SETATTR 0x00000020UL +#define KEY_SOCKET__LOCK 0x00000040UL +#define KEY_SOCKET__RELABELFROM 0x00000080UL +#define KEY_SOCKET__RELABELTO 0x00000100UL +#define KEY_SOCKET__APPEND 0x00000200UL +#define KEY_SOCKET__BIND 0x00000400UL +#define KEY_SOCKET__CONNECT 0x00000800UL +#define KEY_SOCKET__LISTEN 0x00001000UL +#define KEY_SOCKET__ACCEPT 0x00002000UL +#define KEY_SOCKET__GETOPT 0x00004000UL +#define KEY_SOCKET__SETOPT 0x00008000UL +#define KEY_SOCKET__SHUTDOWN 0x00010000UL +#define KEY_SOCKET__RECVFROM 0x00020000UL +#define KEY_SOCKET__SENDTO 0x00040000UL +#define KEY_SOCKET__RECV_MSG 0x00080000UL +#define KEY_SOCKET__SEND_MSG 0x00100000UL +#define KEY_SOCKET__NAME_BIND 0x00200000UL +#define UNIX_STREAM_SOCKET__IOCTL 0x00000001UL +#define UNIX_STREAM_SOCKET__READ 0x00000002UL +#define UNIX_STREAM_SOCKET__WRITE 0x00000004UL +#define UNIX_STREAM_SOCKET__CREATE 0x00000008UL +#define UNIX_STREAM_SOCKET__GETATTR 0x00000010UL +#define UNIX_STREAM_SOCKET__SETATTR 0x00000020UL +#define UNIX_STREAM_SOCKET__LOCK 0x00000040UL +#define UNIX_STREAM_SOCKET__RELABELFROM 0x00000080UL +#define UNIX_STREAM_SOCKET__RELABELTO 0x00000100UL +#define UNIX_STREAM_SOCKET__APPEND 0x00000200UL +#define UNIX_STREAM_SOCKET__BIND 0x00000400UL +#define UNIX_STREAM_SOCKET__CONNECT 0x00000800UL +#define UNIX_STREAM_SOCKET__LISTEN 0x00001000UL +#define UNIX_STREAM_SOCKET__ACCEPT 0x00002000UL +#define UNIX_STREAM_SOCKET__GETOPT 0x00004000UL +#define UNIX_STREAM_SOCKET__SETOPT 0x00008000UL +#define UNIX_STREAM_SOCKET__SHUTDOWN 0x00010000UL +#define UNIX_STREAM_SOCKET__RECVFROM 0x00020000UL +#define UNIX_STREAM_SOCKET__SENDTO 0x00040000UL +#define UNIX_STREAM_SOCKET__RECV_MSG 0x00080000UL +#define UNIX_STREAM_SOCKET__SEND_MSG 0x00100000UL +#define UNIX_STREAM_SOCKET__NAME_BIND 0x00200000UL +#define UNIX_STREAM_SOCKET__CONNECTTO 0x00400000UL +#define UNIX_STREAM_SOCKET__NEWCONN 0x00800000UL +#define UNIX_STREAM_SOCKET__ACCEPTFROM 0x01000000UL +#define UNIX_DGRAM_SOCKET__IOCTL 0x00000001UL +#define UNIX_DGRAM_SOCKET__READ 0x00000002UL +#define UNIX_DGRAM_SOCKET__WRITE 0x00000004UL +#define UNIX_DGRAM_SOCKET__CREATE 0x00000008UL +#define UNIX_DGRAM_SOCKET__GETATTR 0x00000010UL +#define UNIX_DGRAM_SOCKET__SETATTR 0x00000020UL +#define UNIX_DGRAM_SOCKET__LOCK 0x00000040UL +#define UNIX_DGRAM_SOCKET__RELABELFROM 0x00000080UL +#define UNIX_DGRAM_SOCKET__RELABELTO 0x00000100UL +#define UNIX_DGRAM_SOCKET__APPEND 0x00000200UL +#define UNIX_DGRAM_SOCKET__BIND 0x00000400UL +#define UNIX_DGRAM_SOCKET__CONNECT 0x00000800UL +#define UNIX_DGRAM_SOCKET__LISTEN 0x00001000UL +#define UNIX_DGRAM_SOCKET__ACCEPT 0x00002000UL +#define UNIX_DGRAM_SOCKET__GETOPT 0x00004000UL +#define UNIX_DGRAM_SOCKET__SETOPT 0x00008000UL +#define UNIX_DGRAM_SOCKET__SHUTDOWN 0x00010000UL +#define UNIX_DGRAM_SOCKET__RECVFROM 0x00020000UL +#define UNIX_DGRAM_SOCKET__SENDTO 0x00040000UL +#define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL +#define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL +#define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL +#define TUN_SOCKET__IOCTL 0x00000001UL +#define TUN_SOCKET__READ 0x00000002UL +#define TUN_SOCKET__WRITE 0x00000004UL +#define TUN_SOCKET__CREATE 0x00000008UL +#define TUN_SOCKET__GETATTR 0x00000010UL +#define TUN_SOCKET__SETATTR 0x00000020UL +#define TUN_SOCKET__LOCK 0x00000040UL +#define TUN_SOCKET__RELABELFROM 0x00000080UL +#define TUN_SOCKET__RELABELTO 0x00000100UL +#define TUN_SOCKET__APPEND 0x00000200UL +#define TUN_SOCKET__BIND 0x00000400UL +#define TUN_SOCKET__CONNECT 0x00000800UL +#define TUN_SOCKET__LISTEN 0x00001000UL +#define TUN_SOCKET__ACCEPT 0x00002000UL +#define TUN_SOCKET__GETOPT 0x00004000UL +#define TUN_SOCKET__SETOPT 0x00008000UL +#define TUN_SOCKET__SHUTDOWN 0x00010000UL +#define TUN_SOCKET__RECVFROM 0x00020000UL +#define TUN_SOCKET__SENDTO 0x00040000UL +#define TUN_SOCKET__RECV_MSG 0x00080000UL +#define TUN_SOCKET__SEND_MSG 0x00100000UL +#define TUN_SOCKET__NAME_BIND 0x00200000UL +#define PROCESS__FORK 0x00000001UL +#define PROCESS__TRANSITION 0x00000002UL +#define PROCESS__SIGCHLD 0x00000004UL +#define PROCESS__SIGKILL 0x00000008UL +#define PROCESS__SIGSTOP 0x00000010UL +#define PROCESS__SIGNULL 0x00000020UL +#define PROCESS__SIGNAL 0x00000040UL +#define PROCESS__PTRACE 0x00000080UL +#define PROCESS__GETSCHED 0x00000100UL +#define PROCESS__SETSCHED 0x00000200UL +#define PROCESS__GETSESSION 0x00000400UL +#define PROCESS__GETPGID 0x00000800UL +#define PROCESS__SETPGID 0x00001000UL +#define PROCESS__GETCAP 0x00002000UL +#define PROCESS__SETCAP 0x00004000UL +#define PROCESS__SHARE 0x00008000UL +#define PROCESS__GETATTR 0x00010000UL +#define PROCESS__SETEXEC 0x00020000UL +#define PROCESS__SETFSCREATE 0x00040000UL +#define PROCESS__NOATSECURE 0x00080000UL +#define PROCESS__SIGINH 0x00100000UL +#define PROCESS__SETRLIMIT 0x00200000UL +#define PROCESS__RLIMITINH 0x00400000UL +#define PROCESS__DYNTRANSITION 0x00800000UL +#define PROCESS__SETCURRENT 0x01000000UL +#define PROCESS__EXECMEM 0x02000000UL +#define PROCESS__EXECSTACK 0x04000000UL +#define PROCESS__EXECHEAP 0x08000000UL +#define PROCESS__SETKEYCREATE 0x10000000UL +#define PROCESS__SETSOCKCREATE 0x20000000UL +#define IPC__CREATE 0x00000001UL +#define IPC__DESTROY 0x00000002UL +#define IPC__GETATTR 0x00000004UL +#define IPC__SETATTR 0x00000008UL +#define IPC__READ 0x00000010UL +#define IPC__WRITE 0x00000020UL +#define IPC__ASSOCIATE 0x00000040UL +#define IPC__UNIX_READ 0x00000080UL +#define IPC__UNIX_WRITE 0x00000100UL +#define SEM__CREATE 0x00000001UL +#define SEM__DESTROY 0x00000002UL +#define SEM__GETATTR 0x00000004UL +#define SEM__SETATTR 0x00000008UL +#define SEM__READ 0x00000010UL +#define SEM__WRITE 0x00000020UL +#define SEM__ASSOCIATE 0x00000040UL +#define SEM__UNIX_READ 0x00000080UL +#define SEM__UNIX_WRITE 0x00000100UL +#define MSGQ__CREATE 0x00000001UL +#define MSGQ__DESTROY 0x00000002UL +#define MSGQ__GETATTR 0x00000004UL +#define MSGQ__SETATTR 0x00000008UL +#define MSGQ__READ 0x00000010UL +#define MSGQ__WRITE 0x00000020UL +#define MSGQ__ASSOCIATE 0x00000040UL +#define MSGQ__UNIX_READ 0x00000080UL +#define MSGQ__UNIX_WRITE 0x00000100UL +#define MSGQ__ENQUEUE 0x00000200UL +#define MSG__SEND 0x00000001UL +#define MSG__RECEIVE 0x00000002UL +#define SHM__CREATE 0x00000001UL +#define SHM__DESTROY 0x00000002UL +#define SHM__GETATTR 0x00000004UL +#define SHM__SETATTR 0x00000008UL +#define SHM__READ 0x00000010UL +#define SHM__WRITE 0x00000020UL +#define SHM__ASSOCIATE 0x00000040UL +#define SHM__UNIX_READ 0x00000080UL +#define SHM__UNIX_WRITE 0x00000100UL +#define SHM__LOCK 0x00000200UL +#define SECURITY__COMPUTE_AV 0x00000001UL +#define SECURITY__COMPUTE_CREATE 0x00000002UL +#define SECURITY__COMPUTE_MEMBER 0x00000004UL +#define SECURITY__CHECK_CONTEXT 0x00000008UL +#define SECURITY__LOAD_POLICY 0x00000010UL +#define SECURITY__COMPUTE_RELABEL 0x00000020UL +#define SECURITY__COMPUTE_USER 0x00000040UL +#define SECURITY__SETENFORCE 0x00000080UL +#define SECURITY__SETBOOL 0x00000100UL +#define SECURITY__SETSECPARAM 0x00000200UL +#define SECURITY__SETCHECKREQPROT 0x00000400UL +#define SYSTEM__IPC_INFO 0x00000001UL +#define SYSTEM__SYSLOG_READ 0x00000002UL +#define SYSTEM__SYSLOG_MOD 0x00000004UL +#define SYSTEM__SYSLOG_CONSOLE 0x00000008UL +#define SYSTEM__MODULE_REQUEST 0x00000010UL +#define CAPABILITY__CHOWN 0x00000001UL +#define CAPABILITY__DAC_OVERRIDE 0x00000002UL +#define CAPABILITY__DAC_READ_SEARCH 0x00000004UL +#define CAPABILITY__FOWNER 0x00000008UL +#define CAPABILITY__FSETID 0x00000010UL +#define CAPABILITY__KILL 0x00000020UL +#define CAPABILITY__SETGID 0x00000040UL +#define CAPABILITY__SETUID 0x00000080UL +#define CAPABILITY__SETPCAP 0x00000100UL +#define CAPABILITY__LINUX_IMMUTABLE 0x00000200UL +#define CAPABILITY__NET_BIND_SERVICE 0x00000400UL +#define CAPABILITY__NET_BROADCAST 0x00000800UL +#define CAPABILITY__NET_ADMIN 0x00001000UL +#define CAPABILITY__NET_RAW 0x00002000UL +#define CAPABILITY__IPC_LOCK 0x00004000UL +#define CAPABILITY__IPC_OWNER 0x00008000UL +#define CAPABILITY__SYS_MODULE 0x00010000UL +#define CAPABILITY__SYS_RAWIO 0x00020000UL +#define CAPABILITY__SYS_CHROOT 0x00040000UL +#define CAPABILITY__SYS_PTRACE 0x00080000UL +#define CAPABILITY__SYS_PACCT 0x00100000UL +#define CAPABILITY__SYS_ADMIN 0x00200000UL +#define CAPABILITY__SYS_BOOT 0x00400000UL +#define CAPABILITY__SYS_NICE 0x00800000UL +#define CAPABILITY__SYS_RESOURCE 0x01000000UL +#define CAPABILITY__SYS_TIME 0x02000000UL +#define CAPABILITY__SYS_TTY_CONFIG 0x04000000UL +#define CAPABILITY__MKNOD 0x08000000UL +#define CAPABILITY__LEASE 0x10000000UL +#define CAPABILITY__AUDIT_WRITE 0x20000000UL +#define CAPABILITY__AUDIT_CONTROL 0x40000000UL +#define CAPABILITY__SETFCAP 0x80000000UL +#define CAPABILITY2__MAC_OVERRIDE 0x00000001UL +#define CAPABILITY2__MAC_ADMIN 0x00000002UL +#define NETLINK_ROUTE_SOCKET__IOCTL 0x00000001UL +#define NETLINK_ROUTE_SOCKET__READ 0x00000002UL +#define NETLINK_ROUTE_SOCKET__WRITE 0x00000004UL +#define NETLINK_ROUTE_SOCKET__CREATE 0x00000008UL +#define NETLINK_ROUTE_SOCKET__GETATTR 0x00000010UL +#define NETLINK_ROUTE_SOCKET__SETATTR 0x00000020UL +#define NETLINK_ROUTE_SOCKET__LOCK 0x00000040UL +#define NETLINK_ROUTE_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_ROUTE_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_ROUTE_SOCKET__APPEND 0x00000200UL +#define NETLINK_ROUTE_SOCKET__BIND 0x00000400UL +#define NETLINK_ROUTE_SOCKET__CONNECT 0x00000800UL +#define NETLINK_ROUTE_SOCKET__LISTEN 0x00001000UL +#define NETLINK_ROUTE_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_ROUTE_SOCKET__GETOPT 0x00004000UL +#define NETLINK_ROUTE_SOCKET__SETOPT 0x00008000UL +#define NETLINK_ROUTE_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_ROUTE_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_ROUTE_SOCKET__SENDTO 0x00040000UL +#define NETLINK_ROUTE_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_ROUTE_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_ROUTE_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_ROUTE_SOCKET__NLMSG_READ 0x00400000UL +#define NETLINK_ROUTE_SOCKET__NLMSG_WRITE 0x00800000UL +#define NETLINK_FIREWALL_SOCKET__IOCTL 0x00000001UL +#define NETLINK_FIREWALL_SOCKET__READ 0x00000002UL +#define NETLINK_FIREWALL_SOCKET__WRITE 0x00000004UL +#define NETLINK_FIREWALL_SOCKET__CREATE 0x00000008UL +#define NETLINK_FIREWALL_SOCKET__GETATTR 0x00000010UL +#define NETLINK_FIREWALL_SOCKET__SETATTR 0x00000020UL +#define NETLINK_FIREWALL_SOCKET__LOCK 0x00000040UL +#define NETLINK_FIREWALL_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_FIREWALL_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_FIREWALL_SOCKET__APPEND 0x00000200UL +#define NETLINK_FIREWALL_SOCKET__BIND 0x00000400UL +#define NETLINK_FIREWALL_SOCKET__CONNECT 0x00000800UL +#define NETLINK_FIREWALL_SOCKET__LISTEN 0x00001000UL +#define NETLINK_FIREWALL_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_FIREWALL_SOCKET__GETOPT 0x00004000UL +#define NETLINK_FIREWALL_SOCKET__SETOPT 0x00008000UL +#define NETLINK_FIREWALL_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_FIREWALL_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_FIREWALL_SOCKET__SENDTO 0x00040000UL +#define NETLINK_FIREWALL_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_FIREWALL_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_FIREWALL_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_FIREWALL_SOCKET__NLMSG_READ 0x00400000UL +#define NETLINK_FIREWALL_SOCKET__NLMSG_WRITE 0x00800000UL +#define NETLINK_TCPDIAG_SOCKET__IOCTL 0x00000001UL +#define NETLINK_TCPDIAG_SOCKET__READ 0x00000002UL +#define NETLINK_TCPDIAG_SOCKET__WRITE 0x00000004UL +#define NETLINK_TCPDIAG_SOCKET__CREATE 0x00000008UL +#define NETLINK_TCPDIAG_SOCKET__GETATTR 0x00000010UL +#define NETLINK_TCPDIAG_SOCKET__SETATTR 0x00000020UL +#define NETLINK_TCPDIAG_SOCKET__LOCK 0x00000040UL +#define NETLINK_TCPDIAG_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_TCPDIAG_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_TCPDIAG_SOCKET__APPEND 0x00000200UL +#define NETLINK_TCPDIAG_SOCKET__BIND 0x00000400UL +#define NETLINK_TCPDIAG_SOCKET__CONNECT 0x00000800UL +#define NETLINK_TCPDIAG_SOCKET__LISTEN 0x00001000UL +#define NETLINK_TCPDIAG_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_TCPDIAG_SOCKET__GETOPT 0x00004000UL +#define NETLINK_TCPDIAG_SOCKET__SETOPT 0x00008000UL +#define NETLINK_TCPDIAG_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_TCPDIAG_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_TCPDIAG_SOCKET__SENDTO 0x00040000UL +#define NETLINK_TCPDIAG_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_TCPDIAG_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_TCPDIAG_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_TCPDIAG_SOCKET__NLMSG_READ 0x00400000UL +#define NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE 0x00800000UL +#define NETLINK_NFLOG_SOCKET__IOCTL 0x00000001UL +#define NETLINK_NFLOG_SOCKET__READ 0x00000002UL +#define NETLINK_NFLOG_SOCKET__WRITE 0x00000004UL +#define NETLINK_NFLOG_SOCKET__CREATE 0x00000008UL +#define NETLINK_NFLOG_SOCKET__GETATTR 0x00000010UL +#define NETLINK_NFLOG_SOCKET__SETATTR 0x00000020UL +#define NETLINK_NFLOG_SOCKET__LOCK 0x00000040UL +#define NETLINK_NFLOG_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_NFLOG_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_NFLOG_SOCKET__APPEND 0x00000200UL +#define NETLINK_NFLOG_SOCKET__BIND 0x00000400UL +#define NETLINK_NFLOG_SOCKET__CONNECT 0x00000800UL +#define NETLINK_NFLOG_SOCKET__LISTEN 0x00001000UL +#define NETLINK_NFLOG_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_NFLOG_SOCKET__GETOPT 0x00004000UL +#define NETLINK_NFLOG_SOCKET__SETOPT 0x00008000UL +#define NETLINK_NFLOG_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_NFLOG_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_NFLOG_SOCKET__SENDTO 0x00040000UL +#define NETLINK_NFLOG_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_NFLOG_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_NFLOG_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_XFRM_SOCKET__IOCTL 0x00000001UL +#define NETLINK_XFRM_SOCKET__READ 0x00000002UL +#define NETLINK_XFRM_SOCKET__WRITE 0x00000004UL +#define NETLINK_XFRM_SOCKET__CREATE 0x00000008UL +#define NETLINK_XFRM_SOCKET__GETATTR 0x00000010UL +#define NETLINK_XFRM_SOCKET__SETATTR 0x00000020UL +#define NETLINK_XFRM_SOCKET__LOCK 0x00000040UL +#define NETLINK_XFRM_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_XFRM_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_XFRM_SOCKET__APPEND 0x00000200UL +#define NETLINK_XFRM_SOCKET__BIND 0x00000400UL +#define NETLINK_XFRM_SOCKET__CONNECT 0x00000800UL +#define NETLINK_XFRM_SOCKET__LISTEN 0x00001000UL +#define NETLINK_XFRM_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_XFRM_SOCKET__GETOPT 0x00004000UL +#define NETLINK_XFRM_SOCKET__SETOPT 0x00008000UL +#define NETLINK_XFRM_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_XFRM_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_XFRM_SOCKET__SENDTO 0x00040000UL +#define NETLINK_XFRM_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_XFRM_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_XFRM_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_XFRM_SOCKET__NLMSG_READ 0x00400000UL +#define NETLINK_XFRM_SOCKET__NLMSG_WRITE 0x00800000UL +#define NETLINK_SELINUX_SOCKET__IOCTL 0x00000001UL +#define NETLINK_SELINUX_SOCKET__READ 0x00000002UL +#define NETLINK_SELINUX_SOCKET__WRITE 0x00000004UL +#define NETLINK_SELINUX_SOCKET__CREATE 0x00000008UL +#define NETLINK_SELINUX_SOCKET__GETATTR 0x00000010UL +#define NETLINK_SELINUX_SOCKET__SETATTR 0x00000020UL +#define NETLINK_SELINUX_SOCKET__LOCK 0x00000040UL +#define NETLINK_SELINUX_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_SELINUX_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_SELINUX_SOCKET__APPEND 0x00000200UL +#define NETLINK_SELINUX_SOCKET__BIND 0x00000400UL +#define NETLINK_SELINUX_SOCKET__CONNECT 0x00000800UL +#define NETLINK_SELINUX_SOCKET__LISTEN 0x00001000UL +#define NETLINK_SELINUX_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_SELINUX_SOCKET__GETOPT 0x00004000UL +#define NETLINK_SELINUX_SOCKET__SETOPT 0x00008000UL +#define NETLINK_SELINUX_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_SELINUX_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_SELINUX_SOCKET__SENDTO 0x00040000UL +#define NETLINK_SELINUX_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_SELINUX_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_SELINUX_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_AUDIT_SOCKET__IOCTL 0x00000001UL +#define NETLINK_AUDIT_SOCKET__READ 0x00000002UL +#define NETLINK_AUDIT_SOCKET__WRITE 0x00000004UL +#define NETLINK_AUDIT_SOCKET__CREATE 0x00000008UL +#define NETLINK_AUDIT_SOCKET__GETATTR 0x00000010UL +#define NETLINK_AUDIT_SOCKET__SETATTR 0x00000020UL +#define NETLINK_AUDIT_SOCKET__LOCK 0x00000040UL +#define NETLINK_AUDIT_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_AUDIT_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_AUDIT_SOCKET__APPEND 0x00000200UL +#define NETLINK_AUDIT_SOCKET__BIND 0x00000400UL +#define NETLINK_AUDIT_SOCKET__CONNECT 0x00000800UL +#define NETLINK_AUDIT_SOCKET__LISTEN 0x00001000UL +#define NETLINK_AUDIT_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_AUDIT_SOCKET__GETOPT 0x00004000UL +#define NETLINK_AUDIT_SOCKET__SETOPT 0x00008000UL +#define NETLINK_AUDIT_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_AUDIT_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_AUDIT_SOCKET__SENDTO 0x00040000UL +#define NETLINK_AUDIT_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_AUDIT_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_AUDIT_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_AUDIT_SOCKET__NLMSG_READ 0x00400000UL +#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL +#define NETLINK_AUDIT_SOCKET__NLMSG_RELAY 0x01000000UL +#define NETLINK_AUDIT_SOCKET__NLMSG_READPRIV 0x02000000UL +#define NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT 0x04000000UL +#define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL +#define NETLINK_IP6FW_SOCKET__READ 0x00000002UL +#define NETLINK_IP6FW_SOCKET__WRITE 0x00000004UL +#define NETLINK_IP6FW_SOCKET__CREATE 0x00000008UL +#define NETLINK_IP6FW_SOCKET__GETATTR 0x00000010UL +#define NETLINK_IP6FW_SOCKET__SETATTR 0x00000020UL +#define NETLINK_IP6FW_SOCKET__LOCK 0x00000040UL +#define NETLINK_IP6FW_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_IP6FW_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_IP6FW_SOCKET__APPEND 0x00000200UL +#define NETLINK_IP6FW_SOCKET__BIND 0x00000400UL +#define NETLINK_IP6FW_SOCKET__CONNECT 0x00000800UL +#define NETLINK_IP6FW_SOCKET__LISTEN 0x00001000UL +#define NETLINK_IP6FW_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_IP6FW_SOCKET__GETOPT 0x00004000UL +#define NETLINK_IP6FW_SOCKET__SETOPT 0x00008000UL +#define NETLINK_IP6FW_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_IP6FW_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_IP6FW_SOCKET__SENDTO 0x00040000UL +#define NETLINK_IP6FW_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_IP6FW_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_IP6FW_SOCKET__NAME_BIND 0x00200000UL +#define NETLINK_IP6FW_SOCKET__NLMSG_READ 0x00400000UL +#define NETLINK_IP6FW_SOCKET__NLMSG_WRITE 0x00800000UL +#define NETLINK_DNRT_SOCKET__IOCTL 0x00000001UL +#define NETLINK_DNRT_SOCKET__READ 0x00000002UL +#define NETLINK_DNRT_SOCKET__WRITE 0x00000004UL +#define NETLINK_DNRT_SOCKET__CREATE 0x00000008UL +#define NETLINK_DNRT_SOCKET__GETATTR 0x00000010UL +#define NETLINK_DNRT_SOCKET__SETATTR 0x00000020UL +#define NETLINK_DNRT_SOCKET__LOCK 0x00000040UL +#define NETLINK_DNRT_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_DNRT_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_DNRT_SOCKET__APPEND 0x00000200UL +#define NETLINK_DNRT_SOCKET__BIND 0x00000400UL +#define NETLINK_DNRT_SOCKET__CONNECT 0x00000800UL +#define NETLINK_DNRT_SOCKET__LISTEN 0x00001000UL +#define NETLINK_DNRT_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_DNRT_SOCKET__GETOPT 0x00004000UL +#define NETLINK_DNRT_SOCKET__SETOPT 0x00008000UL +#define NETLINK_DNRT_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_DNRT_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_DNRT_SOCKET__SENDTO 0x00040000UL +#define NETLINK_DNRT_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_DNRT_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_DNRT_SOCKET__NAME_BIND 0x00200000UL +#define ASSOCIATION__SENDTO 0x00000001UL +#define ASSOCIATION__RECVFROM 0x00000002UL +#define ASSOCIATION__SETCONTEXT 0x00000004UL +#define ASSOCIATION__POLMATCH 0x00000008UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__WRITE 0x00000004UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__CREATE 0x00000008UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__GETATTR 0x00000010UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__SETATTR 0x00000020UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__LOCK 0x00000040UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELFROM 0x00000080UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELTO 0x00000100UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__APPEND 0x00000200UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__BIND 0x00000400UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__CONNECT 0x00000800UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__LISTEN 0x00001000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__ACCEPT 0x00002000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__GETOPT 0x00004000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__SETOPT 0x00008000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__SHUTDOWN 0x00010000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__RECVFROM 0x00020000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__SENDTO 0x00040000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__RECV_MSG 0x00080000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__SEND_MSG 0x00100000UL +#define NETLINK_KOBJECT_UEVENT_SOCKET__NAME_BIND 0x00200000UL +#define APPLETALK_SOCKET__IOCTL 0x00000001UL +#define APPLETALK_SOCKET__READ 0x00000002UL +#define APPLETALK_SOCKET__WRITE 0x00000004UL +#define APPLETALK_SOCKET__CREATE 0x00000008UL +#define APPLETALK_SOCKET__GETATTR 0x00000010UL +#define APPLETALK_SOCKET__SETATTR 0x00000020UL +#define APPLETALK_SOCKET__LOCK 0x00000040UL +#define APPLETALK_SOCKET__RELABELFROM 0x00000080UL +#define APPLETALK_SOCKET__RELABELTO 0x00000100UL +#define APPLETALK_SOCKET__APPEND 0x00000200UL +#define APPLETALK_SOCKET__BIND 0x00000400UL +#define APPLETALK_SOCKET__CONNECT 0x00000800UL +#define APPLETALK_SOCKET__LISTEN 0x00001000UL +#define APPLETALK_SOCKET__ACCEPT 0x00002000UL +#define APPLETALK_SOCKET__GETOPT 0x00004000UL +#define APPLETALK_SOCKET__SETOPT 0x00008000UL +#define APPLETALK_SOCKET__SHUTDOWN 0x00010000UL +#define APPLETALK_SOCKET__RECVFROM 0x00020000UL +#define APPLETALK_SOCKET__SENDTO 0x00040000UL +#define APPLETALK_SOCKET__RECV_MSG 0x00080000UL +#define APPLETALK_SOCKET__SEND_MSG 0x00100000UL +#define APPLETALK_SOCKET__NAME_BIND 0x00200000UL +#define PACKET__SEND 0x00000001UL +#define PACKET__RECV 0x00000002UL +#define PACKET__RELABELTO 0x00000004UL +#define PACKET__FLOW_IN 0x00000008UL +#define PACKET__FLOW_OUT 0x00000010UL +#define PACKET__FORWARD_IN 0x00000020UL +#define PACKET__FORWARD_OUT 0x00000040UL +#define KEY__VIEW 0x00000001UL +#define KEY__READ 0x00000002UL +#define KEY__WRITE 0x00000004UL +#define KEY__SEARCH 0x00000008UL +#define KEY__LINK 0x00000010UL +#define KEY__SETATTR 0x00000020UL +#define KEY__CREATE 0x00000040UL +#define DCCP_SOCKET__IOCTL 0x00000001UL +#define DCCP_SOCKET__READ 0x00000002UL +#define DCCP_SOCKET__WRITE 0x00000004UL +#define DCCP_SOCKET__CREATE 0x00000008UL +#define DCCP_SOCKET__GETATTR 0x00000010UL +#define DCCP_SOCKET__SETATTR 0x00000020UL +#define DCCP_SOCKET__LOCK 0x00000040UL +#define DCCP_SOCKET__RELABELFROM 0x00000080UL +#define DCCP_SOCKET__RELABELTO 0x00000100UL +#define DCCP_SOCKET__APPEND 0x00000200UL +#define DCCP_SOCKET__BIND 0x00000400UL +#define DCCP_SOCKET__CONNECT 0x00000800UL +#define DCCP_SOCKET__LISTEN 0x00001000UL +#define DCCP_SOCKET__ACCEPT 0x00002000UL +#define DCCP_SOCKET__GETOPT 0x00004000UL +#define DCCP_SOCKET__SETOPT 0x00008000UL +#define DCCP_SOCKET__SHUTDOWN 0x00010000UL +#define DCCP_SOCKET__RECVFROM 0x00020000UL +#define DCCP_SOCKET__SENDTO 0x00040000UL +#define DCCP_SOCKET__RECV_MSG 0x00080000UL +#define DCCP_SOCKET__SEND_MSG 0x00100000UL +#define DCCP_SOCKET__NAME_BIND 0x00200000UL +#define DCCP_SOCKET__NODE_BIND 0x00400000UL +#define DCCP_SOCKET__NAME_CONNECT 0x00800000UL +#define MEMPROTECT__MMAP_ZERO 0x00000001UL +#define PEER__RECV 0x00000001UL +#define KERNEL_SERVICE__USE_AS_OVERRIDE 0x00000001UL +#define KERNEL_SERVICE__CREATE_FILES_AS 0x00000002UL diff --git a/trunk/security/selinux/include/avc_ss.h b/trunk/security/selinux/include/avc_ss.h index 4677aa519b04..bb1ec801bdfe 100644 --- a/trunk/security/selinux/include/avc_ss.h +++ b/trunk/security/selinux/include/avc_ss.h @@ -10,13 +10,26 @@ int avc_ss_reset(u32 seqno); -/* Class/perm mapping support */ -struct security_class_mapping { +struct av_perm_to_string { + u16 tclass; + u32 value; const char *name; - const char *perms[sizeof(u32) * 8 + 1]; }; -extern struct security_class_mapping secclass_map[]; +struct av_inherit { + const char **common_pts; + u32 common_base; + u16 tclass; +}; + +struct selinux_class_perm { + const struct av_perm_to_string *av_perm_to_string; + u32 av_pts_len; + u32 cts_len; + const char **class_to_string; + const struct av_inherit *av_inherit; + u32 av_inherit_len; +}; #endif /* _SELINUX_AVC_SS_H_ */ diff --git a/trunk/security/selinux/include/class_to_string.h b/trunk/security/selinux/include/class_to_string.h new file mode 100644 index 000000000000..7ab9299bfb6b --- /dev/null +++ b/trunk/security/selinux/include/class_to_string.h @@ -0,0 +1,80 @@ +/* This file is automatically generated. Do not edit. */ +/* + * Security object class definitions + */ + S_(NULL) + S_("security") + S_("process") + S_("system") + S_("capability") + S_("filesystem") + S_("file") + S_("dir") + S_("fd") + S_("lnk_file") + S_("chr_file") + S_("blk_file") + S_("sock_file") + S_("fifo_file") + S_("socket") + S_("tcp_socket") + S_("udp_socket") + S_("rawip_socket") + S_("node") + S_("netif") + S_("netlink_socket") + S_("packet_socket") + S_("key_socket") + S_("unix_stream_socket") + S_("unix_dgram_socket") + S_("sem") + S_("msg") + S_("msgq") + S_("shm") + S_("ipc") + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_("netlink_route_socket") + S_("netlink_firewall_socket") + S_("netlink_tcpdiag_socket") + S_("netlink_nflog_socket") + S_("netlink_xfrm_socket") + S_("netlink_selinux_socket") + S_("netlink_audit_socket") + S_("netlink_ip6fw_socket") + S_("netlink_dnrt_socket") + S_(NULL) + S_(NULL) + S_("association") + S_("netlink_kobject_uevent_socket") + S_("appletalk_socket") + S_("packet") + S_("key") + S_(NULL) + S_("dccp_socket") + S_("memprotect") + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_("peer") + S_("capability2") + S_(NULL) + S_(NULL) + S_(NULL) + S_(NULL) + S_("kernel_service") + S_("tun_socket") diff --git a/trunk/security/selinux/include/classmap.h b/trunk/security/selinux/include/classmap.h deleted file mode 100644 index 8b32e959bb2e..000000000000 --- a/trunk/security/selinux/include/classmap.h +++ /dev/null @@ -1,150 +0,0 @@ -#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ - "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append" - -#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ - "rename", "execute", "swapon", "quotaon", "mounton" - -#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \ - "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \ - "sendto", "recv_msg", "send_msg", "name_bind" - -#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ - "write", "associate", "unix_read", "unix_write" - -struct security_class_mapping secclass_map[] = { - { "security", - { "compute_av", "compute_create", "compute_member", - "check_context", "load_policy", "compute_relabel", - "compute_user", "setenforce", "setbool", "setsecparam", - "setcheckreqprot", NULL } }, - { "process", - { "fork", "transition", "sigchld", "sigkill", - "sigstop", "signull", "signal", "ptrace", "getsched", "setsched", - "getsession", "getpgid", "setpgid", "getcap", "setcap", "share", - "getattr", "setexec", "setfscreate", "noatsecure", "siginh", - "setrlimit", "rlimitinh", "dyntransition", "setcurrent", - "execmem", "execstack", "execheap", "setkeycreate", - "setsockcreate", NULL } }, - { "system", - { "ipc_info", "syslog_read", "syslog_mod", - "syslog_console", "module_request", NULL } }, - { "capability", - { "chown", "dac_override", "dac_read_search", - "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", - "linux_immutable", "net_bind_service", "net_broadcast", - "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module", - "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", - "sys_boot", "sys_nice", "sys_resource", "sys_time", - "sys_tty_config", "mknod", "lease", "audit_write", - "audit_control", "setfcap", NULL } }, - { "filesystem", - { "mount", "remount", "unmount", "getattr", - "relabelfrom", "relabelto", "transition", "associate", "quotamod", - "quotaget", NULL } }, - { "file", - { COMMON_FILE_PERMS, - "execute_no_trans", "entrypoint", "execmod", "open", NULL } }, - { "dir", - { COMMON_FILE_PERMS, "add_name", "remove_name", - "reparent", "search", "rmdir", "open", NULL } }, - { "fd", { "use", NULL } }, - { "lnk_file", - { COMMON_FILE_PERMS, NULL } }, - { "chr_file", - { COMMON_FILE_PERMS, - "execute_no_trans", "entrypoint", "execmod", "open", NULL } }, - { "blk_file", - { COMMON_FILE_PERMS, "open", NULL } }, - { "sock_file", - { COMMON_FILE_PERMS, "open", NULL } }, - { "fifo_file", - { COMMON_FILE_PERMS, "open", NULL } }, - { "socket", - { COMMON_SOCK_PERMS, NULL } }, - { "tcp_socket", - { COMMON_SOCK_PERMS, - "connectto", "newconn", "acceptfrom", "node_bind", "name_connect", - NULL } }, - { "udp_socket", - { COMMON_SOCK_PERMS, - "node_bind", NULL } }, - { "rawip_socket", - { COMMON_SOCK_PERMS, - "node_bind", NULL } }, - { "node", - { "tcp_recv", "tcp_send", "udp_recv", "udp_send", - "rawip_recv", "rawip_send", "enforce_dest", - "dccp_recv", "dccp_send", "recvfrom", "sendto", NULL } }, - { "netif", - { "tcp_recv", "tcp_send", "udp_recv", "udp_send", - "rawip_recv", "rawip_send", "dccp_recv", "dccp_send", - "ingress", "egress", NULL } }, - { "netlink_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "packet_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "key_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "unix_stream_socket", - { COMMON_SOCK_PERMS, "connectto", "newconn", "acceptfrom", NULL - } }, - { "unix_dgram_socket", - { COMMON_SOCK_PERMS, NULL - } }, - { "sem", - { COMMON_IPC_PERMS, NULL } }, - { "msg", { "send", "receive", NULL } }, - { "msgq", - { COMMON_IPC_PERMS, "enqueue", NULL } }, - { "shm", - { COMMON_IPC_PERMS, "lock", NULL } }, - { "ipc", - { COMMON_IPC_PERMS, NULL } }, - { "netlink_route_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_firewall_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_tcpdiag_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_nflog_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "netlink_xfrm_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_selinux_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "netlink_audit_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv", - "nlmsg_tty_audit", NULL } }, - { "netlink_ip6fw_socket", - { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, - { "netlink_dnrt_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "association", - { "sendto", "recvfrom", "setcontext", "polmatch", NULL } }, - { "netlink_kobject_uevent_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "appletalk_socket", - { COMMON_SOCK_PERMS, NULL } }, - { "packet", - { "send", "recv", "relabelto", "flow_in", "flow_out", - "forward_in", "forward_out", NULL } }, - { "key", - { "view", "read", "write", "search", "link", "setattr", "create", - NULL } }, - { "dccp_socket", - { COMMON_SOCK_PERMS, - "node_bind", "name_connect", NULL } }, - { "memprotect", { "mmap_zero", NULL } }, - { "peer", { "recv", NULL } }, - { "capability2", { "mac_override", "mac_admin", NULL } }, - { "kernel_service", { "use_as_override", "create_files_as", NULL } }, - { "tun_socket", - { COMMON_SOCK_PERMS, NULL } }, - { NULL } - }; diff --git a/trunk/security/selinux/include/common_perm_to_string.h b/trunk/security/selinux/include/common_perm_to_string.h new file mode 100644 index 000000000000..ce5b6e2fe9dd --- /dev/null +++ b/trunk/security/selinux/include/common_perm_to_string.h @@ -0,0 +1,58 @@ +/* This file is automatically generated. Do not edit. */ +TB_(common_file_perm_to_string) + S_("ioctl") + S_("read") + S_("write") + S_("create") + S_("getattr") + S_("setattr") + S_("lock") + S_("relabelfrom") + S_("relabelto") + S_("append") + S_("unlink") + S_("link") + S_("rename") + S_("execute") + S_("swapon") + S_("quotaon") + S_("mounton") +TE_(common_file_perm_to_string) + +TB_(common_socket_perm_to_string) + S_("ioctl") + S_("read") + S_("write") + S_("create") + S_("getattr") + S_("setattr") + S_("lock") + S_("relabelfrom") + S_("relabelto") + S_("append") + S_("bind") + S_("connect") + S_("listen") + S_("accept") + S_("getopt") + S_("setopt") + S_("shutdown") + S_("recvfrom") + S_("sendto") + S_("recv_msg") + S_("send_msg") + S_("name_bind") +TE_(common_socket_perm_to_string) + +TB_(common_ipc_perm_to_string) + S_("create") + S_("destroy") + S_("getattr") + S_("setattr") + S_("read") + S_("write") + S_("associate") + S_("unix_read") + S_("unix_write") +TE_(common_ipc_perm_to_string) + diff --git a/trunk/security/selinux/include/flask.h b/trunk/security/selinux/include/flask.h new file mode 100644 index 000000000000..f248500a1e3c --- /dev/null +++ b/trunk/security/selinux/include/flask.h @@ -0,0 +1,91 @@ +/* This file is automatically generated. Do not edit. */ +#ifndef _SELINUX_FLASK_H_ +#define _SELINUX_FLASK_H_ + +/* + * Security object class definitions + */ +#define SECCLASS_SECURITY 1 +#define SECCLASS_PROCESS 2 +#define SECCLASS_SYSTEM 3 +#define SECCLASS_CAPABILITY 4 +#define SECCLASS_FILESYSTEM 5 +#define SECCLASS_FILE 6 +#define SECCLASS_DIR 7 +#define SECCLASS_FD 8 +#define SECCLASS_LNK_FILE 9 +#define SECCLASS_CHR_FILE 10 +#define SECCLASS_BLK_FILE 11 +#define SECCLASS_SOCK_FILE 12 +#define SECCLASS_FIFO_FILE 13 +#define SECCLASS_SOCKET 14 +#define SECCLASS_TCP_SOCKET 15 +#define SECCLASS_UDP_SOCKET 16 +#define SECCLASS_RAWIP_SOCKET 17 +#define SECCLASS_NODE 18 +#define SECCLASS_NETIF 19 +#define SECCLASS_NETLINK_SOCKET 20 +#define SECCLASS_PACKET_SOCKET 21 +#define SECCLASS_KEY_SOCKET 22 +#define SECCLASS_UNIX_STREAM_SOCKET 23 +#define SECCLASS_UNIX_DGRAM_SOCKET 24 +#define SECCLASS_SEM 25 +#define SECCLASS_MSG 26 +#define SECCLASS_MSGQ 27 +#define SECCLASS_SHM 28 +#define SECCLASS_IPC 29 +#define SECCLASS_NETLINK_ROUTE_SOCKET 43 +#define SECCLASS_NETLINK_FIREWALL_SOCKET 44 +#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45 +#define SECCLASS_NETLINK_NFLOG_SOCKET 46 +#define SECCLASS_NETLINK_XFRM_SOCKET 47 +#define SECCLASS_NETLINK_SELINUX_SOCKET 48 +#define SECCLASS_NETLINK_AUDIT_SOCKET 49 +#define SECCLASS_NETLINK_IP6FW_SOCKET 50 +#define SECCLASS_NETLINK_DNRT_SOCKET 51 +#define SECCLASS_ASSOCIATION 54 +#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55 +#define SECCLASS_APPLETALK_SOCKET 56 +#define SECCLASS_PACKET 57 +#define SECCLASS_KEY 58 +#define SECCLASS_DCCP_SOCKET 60 +#define SECCLASS_MEMPROTECT 61 +#define SECCLASS_PEER 68 +#define SECCLASS_CAPABILITY2 69 +#define SECCLASS_KERNEL_SERVICE 74 +#define SECCLASS_TUN_SOCKET 75 + +/* + * Security identifier indices for initial entities + */ +#define SECINITSID_KERNEL 1 +#define SECINITSID_SECURITY 2 +#define SECINITSID_UNLABELED 3 +#define SECINITSID_FS 4 +#define SECINITSID_FILE 5 +#define SECINITSID_FILE_LABELS 6 +#define SECINITSID_INIT 7 +#define SECINITSID_ANY_SOCKET 8 +#define SECINITSID_PORT 9 +#define SECINITSID_NETIF 10 +#define SECINITSID_NETMSG 11 +#define SECINITSID_NODE 12 +#define SECINITSID_IGMP_PACKET 13 +#define SECINITSID_ICMP_SOCKET 14 +#define SECINITSID_TCP_SOCKET 15 +#define SECINITSID_SYSCTL_MODPROBE 16 +#define SECINITSID_SYSCTL 17 +#define SECINITSID_SYSCTL_FS 18 +#define SECINITSID_SYSCTL_KERNEL 19 +#define SECINITSID_SYSCTL_NET 20 +#define SECINITSID_SYSCTL_NET_UNIX 21 +#define SECINITSID_SYSCTL_VM 22 +#define SECINITSID_SYSCTL_DEV 23 +#define SECINITSID_KMOD 24 +#define SECINITSID_POLICY 25 +#define SECINITSID_SCMP_PACKET 26 +#define SECINITSID_DEVNULL 27 + +#define SECINITSID_NUM 27 + +#endif diff --git a/trunk/security/selinux/include/security.h b/trunk/security/selinux/include/security.h index 2553266ad793..ca835795a8b3 100644 --- a/trunk/security/selinux/include/security.h +++ b/trunk/security/selinux/include/security.h @@ -97,18 +97,11 @@ struct av_decision { #define AVD_FLAGS_PERMISSIVE 0x0001 int security_compute_av(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct av_decision *avd); - -int security_compute_av_user(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct av_decision *avd); + u16 tclass, u32 requested, + struct av_decision *avd); int security_transition_sid(u32 ssid, u32 tsid, - u16 tclass, u32 *out_sid); - -int security_transition_sid_user(u32 ssid, u32 tsid, - u16 tclass, u32 *out_sid); + u16 tclass, u32 *out_sid); int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid); diff --git a/trunk/security/selinux/selinuxfs.c b/trunk/security/selinux/selinuxfs.c index fab36fdf2769..b4fc506e7a87 100644 --- a/trunk/security/selinux/selinuxfs.c +++ b/trunk/security/selinux/selinuxfs.c @@ -522,7 +522,7 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) if (length < 0) goto out2; - length = security_compute_av_user(ssid, tsid, tclass, req, &avd); + length = security_compute_av(ssid, tsid, tclass, req, &avd); if (length < 0) goto out2; @@ -571,7 +571,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) if (length < 0) goto out2; - length = security_transition_sid_user(ssid, tsid, tclass, &newsid); + length = security_transition_sid(ssid, tsid, tclass, &newsid); if (length < 0) goto out2; diff --git a/trunk/security/selinux/ss/Makefile b/trunk/security/selinux/ss/Makefile index 15d4e62917de..bad78779b9b0 100644 --- a/trunk/security/selinux/ss/Makefile +++ b/trunk/security/selinux/ss/Makefile @@ -2,7 +2,7 @@ # Makefile for building the SELinux security server as part of the kernel tree. # -EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include +EXTRA_CFLAGS += -Isecurity/selinux/include obj-y := ss.o ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o diff --git a/trunk/security/selinux/ss/mls.c b/trunk/security/selinux/ss/mls.c index 3f2b2706b5bb..b5407f16c2a4 100644 --- a/trunk/security/selinux/ss/mls.c +++ b/trunk/security/selinux/ss/mls.c @@ -532,7 +532,7 @@ int mls_compute_sid(struct context *scontext, } /* Fallthrough */ case AVTAB_CHANGE: - if (tclass == policydb.process_class) + if (tclass == SECCLASS_PROCESS) /* Use the process MLS attributes. */ return mls_context_cpy(newcontext, scontext); else diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index f03667213ea8..72e4a54973aa 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -713,6 +713,7 @@ void policydb_destroy(struct policydb *p) ebitmap_destroy(&p->type_attr_map[i]); } kfree(p->type_attr_map); + kfree(p->undefined_perms); ebitmap_destroy(&p->policycaps); ebitmap_destroy(&p->permissive_map); @@ -1639,40 +1640,6 @@ static int policydb_bounds_sanity_check(struct policydb *p) extern int ss_initialized; -u16 string_to_security_class(struct policydb *p, const char *name) -{ - struct class_datum *cladatum; - - cladatum = hashtab_search(p->p_classes.table, name); - if (!cladatum) - return 0; - - return cladatum->value; -} - -u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name) -{ - struct class_datum *cladatum; - struct perm_datum *perdatum = NULL; - struct common_datum *comdatum; - - if (!tclass || tclass > p->p_classes.nprim) - return 0; - - cladatum = p->class_val_to_struct[tclass-1]; - comdatum = cladatum->comdatum; - if (comdatum) - perdatum = hashtab_search(comdatum->permissions.table, - name); - if (!perdatum) - perdatum = hashtab_search(cladatum->permissions.table, - name); - if (!perdatum) - return 0; - - return 1U << (perdatum->value-1); -} - /* * Read the configuration data from a policy database binary * representation file into a policy database structure. @@ -1894,16 +1861,6 @@ int policydb_read(struct policydb *p, void *fp) if (rc) goto bad; - p->process_class = string_to_security_class(p, "process"); - if (!p->process_class) - goto bad; - p->process_trans_perms = string_to_av_perm(p, p->process_class, - "transition"); - p->process_trans_perms |= string_to_av_perm(p, p->process_class, - "dyntransition"); - if (!p->process_trans_perms) - goto bad; - for (i = 0; i < info->ocon_num; i++) { rc = next_entry(buf, fp, sizeof(u32)); if (rc < 0) @@ -2144,7 +2101,7 @@ int policydb_read(struct policydb *p, void *fp) goto bad; rt->target_class = le32_to_cpu(buf[0]); } else - rt->target_class = p->process_class; + rt->target_class = SECCLASS_PROCESS; if (!policydb_type_isvalid(p, rt->source_type) || !policydb_type_isvalid(p, rt->target_type) || !policydb_class_isvalid(p, rt->target_class)) { diff --git a/trunk/security/selinux/ss/policydb.h b/trunk/security/selinux/ss/policydb.h index cdcc5700946f..55152d498b53 100644 --- a/trunk/security/selinux/ss/policydb.h +++ b/trunk/security/selinux/ss/policydb.h @@ -254,9 +254,7 @@ struct policydb { unsigned int reject_unknown : 1; unsigned int allow_unknown : 1; - - u16 process_class; - u32 process_trans_perms; + u32 *undefined_perms; }; extern void policydb_destroy(struct policydb *p); @@ -297,8 +295,5 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) return 0; } -extern u16 string_to_security_class(struct policydb *p, const char *name); -extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); - #endif /* _SS_POLICYDB_H_ */ diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index d6bb20cbad62..ff17820d35ec 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -65,10 +65,16 @@ #include "audit.h" extern void selnl_notify_policyload(u32 seqno); +unsigned int policydb_loaded_version; int selinux_policycap_netpeer; int selinux_policycap_openperm; +/* + * This is declared in avc.c + */ +extern const struct selinux_class_perm selinux_class_perm; + static DEFINE_RWLOCK(policy_rwlock); static struct sidtab sidtab; @@ -92,165 +98,6 @@ static int context_struct_compute_av(struct context *scontext, u16 tclass, u32 requested, struct av_decision *avd); - -struct selinux_mapping { - u16 value; /* policy value */ - unsigned num_perms; - u32 perms[sizeof(u32) * 8]; -}; - -static struct selinux_mapping *current_mapping; -static u16 current_mapping_size; - -static int selinux_set_mapping(struct policydb *pol, - struct security_class_mapping *map, - struct selinux_mapping **out_map_p, - u16 *out_map_size) -{ - struct selinux_mapping *out_map = NULL; - size_t size = sizeof(struct selinux_mapping); - u16 i, j; - unsigned k; - bool print_unknown_handle = false; - - /* Find number of classes in the input mapping */ - if (!map) - return -EINVAL; - i = 0; - while (map[i].name) - i++; - - /* Allocate space for the class records, plus one for class zero */ - out_map = kcalloc(++i, size, GFP_ATOMIC); - if (!out_map) - return -ENOMEM; - - /* Store the raw class and permission values */ - j = 0; - while (map[j].name) { - struct security_class_mapping *p_in = map + (j++); - struct selinux_mapping *p_out = out_map + j; - - /* An empty class string skips ahead */ - if (!strcmp(p_in->name, "")) { - p_out->num_perms = 0; - continue; - } - - p_out->value = string_to_security_class(pol, p_in->name); - if (!p_out->value) { - printk(KERN_INFO - "SELinux: Class %s not defined in policy.\n", - p_in->name); - if (pol->reject_unknown) - goto err; - p_out->num_perms = 0; - print_unknown_handle = true; - continue; - } - - k = 0; - while (p_in->perms && p_in->perms[k]) { - /* An empty permission string skips ahead */ - if (!*p_in->perms[k]) { - k++; - continue; - } - p_out->perms[k] = string_to_av_perm(pol, p_out->value, - p_in->perms[k]); - if (!p_out->perms[k]) { - printk(KERN_INFO - "SELinux: Permission %s in class %s not defined in policy.\n", - p_in->perms[k], p_in->name); - if (pol->reject_unknown) - goto err; - print_unknown_handle = true; - } - - k++; - } - p_out->num_perms = k; - } - - if (print_unknown_handle) - printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n", - pol->allow_unknown ? "allowed" : "denied"); - - *out_map_p = out_map; - *out_map_size = i; - return 0; -err: - kfree(out_map); - return -EINVAL; -} - -/* - * Get real, policy values from mapped values - */ - -static u16 unmap_class(u16 tclass) -{ - if (tclass < current_mapping_size) - return current_mapping[tclass].value; - - return tclass; -} - -static u32 unmap_perm(u16 tclass, u32 tperm) -{ - if (tclass < current_mapping_size) { - unsigned i; - u32 kperm = 0; - - for (i = 0; i < current_mapping[tclass].num_perms; i++) - if (tperm & (1<allowed & current_mapping[tclass].perms[i]) - result |= 1<allowed = result; - - for (i = 0, result = 0; i < n; i++) - if (avd->auditallow & current_mapping[tclass].perms[i]) - result |= 1<auditallow = result; - - for (i = 0, result = 0; i < n; i++) { - if (avd->auditdeny & current_mapping[tclass].perms[i]) - result |= 1<auditdeny = result; - } -} - - /* * Return the boolean value of a constraint expression * when it is applied to the specified source and target @@ -620,8 +467,20 @@ static int context_struct_compute_av(struct context *scontext, struct class_datum *tclass_datum; struct ebitmap *sattr, *tattr; struct ebitmap_node *snode, *tnode; + const struct selinux_class_perm *kdefs = &selinux_class_perm; unsigned int i, j; + /* + * Remap extended Netlink classes for old policy versions. + * Do this here rather than socket_type_to_security_class() + * in case a newer policy version is loaded, allowing sockets + * to remain in the correct class. + */ + if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS) + if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET && + tclass <= SECCLASS_NETLINK_DNRT_SOCKET) + tclass = SECCLASS_NETLINK_SOCKET; + /* * Initialize the access vectors to the default values. */ @@ -631,11 +490,33 @@ static int context_struct_compute_av(struct context *scontext, avd->seqno = latest_granting; avd->flags = 0; - if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { - if (printk_ratelimit()) - printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass); - return -EINVAL; - } + /* + * Check for all the invalid cases. + * - tclass 0 + * - tclass > policy and > kernel + * - tclass > policy but is a userspace class + * - tclass > policy but we do not allow unknowns + */ + if (unlikely(!tclass)) + goto inval_class; + if (unlikely(tclass > policydb.p_classes.nprim)) + if (tclass > kdefs->cts_len || + !kdefs->class_to_string[tclass] || + !policydb.allow_unknown) + goto inval_class; + + /* + * Kernel class and we allow unknown so pad the allow decision + * the pad will be all 1 for unknown classes. + */ + if (tclass <= kdefs->cts_len && policydb.allow_unknown) + avd->allowed = policydb.undefined_perms[tclass - 1]; + + /* + * Not in policy. Since decision is completed (all 1 or all 0) return. + */ + if (unlikely(tclass > policydb.p_classes.nprim)) + return 0; tclass_datum = policydb.class_val_to_struct[tclass - 1]; @@ -687,8 +568,8 @@ static int context_struct_compute_av(struct context *scontext, * role is changing, then check the (current_role, new_role) * pair. */ - if (tclass == policydb.process_class && - (avd->allowed & policydb.process_trans_perms) && + if (tclass == SECCLASS_PROCESS && + (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && scontext->role != tcontext->role) { for (ra = policydb.role_allow; ra; ra = ra->next) { if (scontext->role == ra->role && @@ -696,7 +577,8 @@ static int context_struct_compute_av(struct context *scontext, break; } if (!ra) - avd->allowed &= ~policydb.process_trans_perms; + avd->allowed &= ~(PROCESS__TRANSITION | + PROCESS__DYNTRANSITION); } /* @@ -708,6 +590,21 @@ static int context_struct_compute_av(struct context *scontext, tclass, requested, avd); return 0; + +inval_class: + if (!tclass || tclass > kdefs->cts_len || + !kdefs->class_to_string[tclass]) { + if (printk_ratelimit()) + printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", + __func__, tclass); + return -EINVAL; + } + + /* + * Known to the kernel, but not to the policy. + * Handle as a denial (allowed is 0). + */ + return 0; } static int security_validtrans_handle_fail(struct context *ocontext, @@ -739,14 +636,13 @@ static int security_validtrans_handle_fail(struct context *ocontext, } int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, - u16 orig_tclass) + u16 tclass) { struct context *ocontext; struct context *ncontext; struct context *tcontext; struct class_datum *tclass_datum; struct constraint_node *constraint; - u16 tclass; int rc = 0; if (!ss_initialized) @@ -754,7 +650,16 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, read_lock(&policy_rwlock); - tclass = unmap_class(orig_tclass); + /* + * Remap extended Netlink classes for old policy versions. + * Do this here rather than socket_type_to_security_class() + * in case a newer policy version is loaded, allowing sockets + * to remain in the correct class. + */ + if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS) + if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET && + tclass <= SECCLASS_NETLINK_DNRT_SOCKET) + tclass = SECCLASS_NETLINK_SOCKET; if (!tclass || tclass > policydb.p_classes.nprim) { printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", @@ -887,38 +792,6 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) } -static int security_compute_av_core(u32 ssid, - u32 tsid, - u16 tclass, - u32 requested, - struct av_decision *avd) -{ - struct context *scontext = NULL, *tcontext = NULL; - int rc = 0; - - scontext = sidtab_search(&sidtab, ssid); - if (!scontext) { - printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", - __func__, ssid); - return -EINVAL; - } - tcontext = sidtab_search(&sidtab, tsid); - if (!tcontext) { - printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", - __func__, tsid); - return -EINVAL; - } - - rc = context_struct_compute_av(scontext, tcontext, tclass, - requested, avd); - - /* permissive domain? */ - if (ebitmap_get_bit(&policydb.permissive_map, scontext->type)) - avd->flags |= AVD_FLAGS_PERMISSIVE; - - return rc; -} - /** * security_compute_av - Compute access vector decisions. * @ssid: source security identifier @@ -934,49 +807,12 @@ static int security_compute_av_core(u32 ssid, */ int security_compute_av(u32 ssid, u32 tsid, - u16 orig_tclass, - u32 orig_requested, + u16 tclass, + u32 requested, struct av_decision *avd) { - u16 tclass; - u32 requested; - int rc; - - read_lock(&policy_rwlock); - - if (!ss_initialized) - goto allow; - - requested = unmap_perm(orig_tclass, orig_requested); - tclass = unmap_class(orig_tclass); - if (unlikely(orig_tclass && !tclass)) { - if (policydb.allow_unknown) - goto allow; - rc = -EINVAL; - goto out; - } - rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); - map_decision(orig_tclass, avd, policydb.allow_unknown); -out: - read_unlock(&policy_rwlock); - return rc; -allow: - avd->allowed = 0xffffffff; - avd->auditallow = 0; - avd->auditdeny = 0xffffffff; - avd->seqno = latest_granting; - avd->flags = 0; - rc = 0; - goto out; -} - -int security_compute_av_user(u32 ssid, - u32 tsid, - u16 tclass, - u32 requested, - struct av_decision *avd) -{ - int rc; + struct context *scontext = NULL, *tcontext = NULL; + int rc = 0; if (!ss_initialized) { avd->allowed = 0xffffffff; @@ -987,7 +823,29 @@ int security_compute_av_user(u32 ssid, } read_lock(&policy_rwlock); - rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); + + scontext = sidtab_search(&sidtab, ssid); + if (!scontext) { + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, ssid); + rc = -EINVAL; + goto out; + } + tcontext = sidtab_search(&sidtab, tsid); + if (!tcontext) { + printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", + __func__, tsid); + rc = -EINVAL; + goto out; + } + + rc = context_struct_compute_av(scontext, tcontext, tclass, + requested, avd); + + /* permissive domain? */ + if (ebitmap_get_bit(&policydb.permissive_map, scontext->type)) + avd->flags |= AVD_FLAGS_PERMISSIVE; +out: read_unlock(&policy_rwlock); return rc; } @@ -1346,22 +1204,20 @@ static int compute_sid_handle_invalid_context( static int security_compute_sid(u32 ssid, u32 tsid, - u16 orig_tclass, + u16 tclass, u32 specified, - u32 *out_sid, - bool kern) + u32 *out_sid) { struct context *scontext = NULL, *tcontext = NULL, newcontext; struct role_trans *roletr = NULL; struct avtab_key avkey; struct avtab_datum *avdatum; struct avtab_node *node; - u16 tclass; int rc = 0; if (!ss_initialized) { - switch (orig_tclass) { - case SECCLASS_PROCESS: /* kernel value */ + switch (tclass) { + case SECCLASS_PROCESS: *out_sid = ssid; break; default: @@ -1375,11 +1231,6 @@ static int security_compute_sid(u32 ssid, read_lock(&policy_rwlock); - if (kern) - tclass = unmap_class(orig_tclass); - else - tclass = orig_tclass; - scontext = sidtab_search(&sidtab, ssid); if (!scontext) { printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", @@ -1409,11 +1260,13 @@ static int security_compute_sid(u32 ssid, } /* Set the role and type to default values. */ - if (tclass == policydb.process_class) { + switch (tclass) { + case SECCLASS_PROCESS: /* Use the current role and type of process. */ newcontext.role = scontext->role; newcontext.type = scontext->type; - } else { + break; + default: /* Use the well-defined object role. */ newcontext.role = OBJECT_R_VAL; /* Use the type of the related object. */ @@ -1444,7 +1297,8 @@ static int security_compute_sid(u32 ssid, } /* Check for class-specific changes. */ - if (tclass == policydb.process_class) { + switch (tclass) { + case SECCLASS_PROCESS: if (specified & AVTAB_TRANSITION) { /* Look for a role transition rule. */ for (roletr = policydb.role_tr; roletr; @@ -1457,6 +1311,9 @@ static int security_compute_sid(u32 ssid, } } } + break; + default: + break; } /* Set the MLS attributes. @@ -1501,17 +1358,7 @@ int security_transition_sid(u32 ssid, u16 tclass, u32 *out_sid) { - return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, - out_sid, true); -} - -int security_transition_sid_user(u32 ssid, - u32 tsid, - u16 tclass, - u32 *out_sid) -{ - return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, - out_sid, false); + return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid); } /** @@ -1532,8 +1379,7 @@ int security_member_sid(u32 ssid, u16 tclass, u32 *out_sid) { - return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid, - false); + return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid); } /** @@ -1554,8 +1400,144 @@ int security_change_sid(u32 ssid, u16 tclass, u32 *out_sid) { - return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid, - false); + return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid); +} + +/* + * Verify that each kernel class that is defined in the + * policy is correct + */ +static int validate_classes(struct policydb *p) +{ + int i, j; + struct class_datum *cladatum; + struct perm_datum *perdatum; + u32 nprim, tmp, common_pts_len, perm_val, pol_val; + u16 class_val; + const struct selinux_class_perm *kdefs = &selinux_class_perm; + const char *def_class, *def_perm, *pol_class; + struct symtab *perms; + bool print_unknown_handle = 0; + + if (p->allow_unknown) { + u32 num_classes = kdefs->cts_len; + p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL); + if (!p->undefined_perms) + return -ENOMEM; + } + + for (i = 1; i < kdefs->cts_len; i++) { + def_class = kdefs->class_to_string[i]; + if (!def_class) + continue; + if (i > p->p_classes.nprim) { + printk(KERN_INFO + "SELinux: class %s not defined in policy\n", + def_class); + if (p->reject_unknown) + return -EINVAL; + if (p->allow_unknown) + p->undefined_perms[i-1] = ~0U; + print_unknown_handle = 1; + continue; + } + pol_class = p->p_class_val_to_name[i-1]; + if (strcmp(pol_class, def_class)) { + printk(KERN_ERR + "SELinux: class %d is incorrect, found %s but should be %s\n", + i, pol_class, def_class); + return -EINVAL; + } + } + for (i = 0; i < kdefs->av_pts_len; i++) { + class_val = kdefs->av_perm_to_string[i].tclass; + perm_val = kdefs->av_perm_to_string[i].value; + def_perm = kdefs->av_perm_to_string[i].name; + if (class_val > p->p_classes.nprim) + continue; + pol_class = p->p_class_val_to_name[class_val-1]; + cladatum = hashtab_search(p->p_classes.table, pol_class); + BUG_ON(!cladatum); + perms = &cladatum->permissions; + nprim = 1 << (perms->nprim - 1); + if (perm_val > nprim) { + printk(KERN_INFO + "SELinux: permission %s in class %s not defined in policy\n", + def_perm, pol_class); + if (p->reject_unknown) + return -EINVAL; + if (p->allow_unknown) + p->undefined_perms[class_val-1] |= perm_val; + print_unknown_handle = 1; + continue; + } + perdatum = hashtab_search(perms->table, def_perm); + if (perdatum == NULL) { + printk(KERN_ERR + "SELinux: permission %s in class %s not found in policy, bad policy\n", + def_perm, pol_class); + return -EINVAL; + } + pol_val = 1 << (perdatum->value - 1); + if (pol_val != perm_val) { + printk(KERN_ERR + "SELinux: permission %s in class %s has incorrect value\n", + def_perm, pol_class); + return -EINVAL; + } + } + for (i = 0; i < kdefs->av_inherit_len; i++) { + class_val = kdefs->av_inherit[i].tclass; + if (class_val > p->p_classes.nprim) + continue; + pol_class = p->p_class_val_to_name[class_val-1]; + cladatum = hashtab_search(p->p_classes.table, pol_class); + BUG_ON(!cladatum); + if (!cladatum->comdatum) { + printk(KERN_ERR + "SELinux: class %s should have an inherits clause but does not\n", + pol_class); + return -EINVAL; + } + tmp = kdefs->av_inherit[i].common_base; + common_pts_len = 0; + while (!(tmp & 0x01)) { + common_pts_len++; + tmp >>= 1; + } + perms = &cladatum->comdatum->permissions; + for (j = 0; j < common_pts_len; j++) { + def_perm = kdefs->av_inherit[i].common_pts[j]; + if (j >= perms->nprim) { + printk(KERN_INFO + "SELinux: permission %s in class %s not defined in policy\n", + def_perm, pol_class); + if (p->reject_unknown) + return -EINVAL; + if (p->allow_unknown) + p->undefined_perms[class_val-1] |= (1 << j); + print_unknown_handle = 1; + continue; + } + perdatum = hashtab_search(perms->table, def_perm); + if (perdatum == NULL) { + printk(KERN_ERR + "SELinux: permission %s in class %s not found in policy, bad policy\n", + def_perm, pol_class); + return -EINVAL; + } + if (perdatum->value != j + 1) { + printk(KERN_ERR + "SELinux: permission %s in class %s has incorrect value\n", + def_perm, pol_class); + return -EINVAL; + } + } + } + if (print_unknown_handle) + printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n", + (security_get_allow_unknown() ? "allowed" : "denied")); + return 0; } /* Clone the SID into the new SID table. */ @@ -1728,10 +1710,8 @@ int security_load_policy(void *data, size_t len) { struct policydb oldpolicydb, newpolicydb; struct sidtab oldsidtab, newsidtab; - struct selinux_mapping *oldmap, *map = NULL; struct convert_context_args args; u32 seqno; - u16 map_size; int rc = 0; struct policy_file file = { data, len }, *fp = &file; @@ -1741,19 +1721,22 @@ int security_load_policy(void *data, size_t len) avtab_cache_destroy(); return -EINVAL; } - if (selinux_set_mapping(&policydb, secclass_map, - ¤t_mapping, - ¤t_mapping_size)) { + if (policydb_load_isids(&policydb, &sidtab)) { policydb_destroy(&policydb); avtab_cache_destroy(); return -EINVAL; } - if (policydb_load_isids(&policydb, &sidtab)) { + /* Verify that the kernel defined classes are correct. */ + if (validate_classes(&policydb)) { + printk(KERN_ERR + "SELinux: the definition of a class is incorrect\n"); + sidtab_destroy(&sidtab); policydb_destroy(&policydb); avtab_cache_destroy(); return -EINVAL; } security_load_policycaps(); + policydb_loaded_version = policydb.policyvers; ss_initialized = 1; seqno = ++latest_granting; selinux_complete_init(); @@ -1776,9 +1759,13 @@ int security_load_policy(void *data, size_t len) return -ENOMEM; } - if (selinux_set_mapping(&newpolicydb, secclass_map, - &map, &map_size)) + /* Verify that the kernel defined classes are correct. */ + if (validate_classes(&newpolicydb)) { + printk(KERN_ERR + "SELinux: the definition of a class is incorrect\n"); + rc = -EINVAL; goto err; + } rc = security_preserve_bools(&newpolicydb); if (rc) { @@ -1812,16 +1799,13 @@ int security_load_policy(void *data, size_t len) memcpy(&policydb, &newpolicydb, sizeof policydb); sidtab_set(&sidtab, &newsidtab); security_load_policycaps(); - oldmap = current_mapping; - current_mapping = map; - current_mapping_size = map_size; seqno = ++latest_granting; + policydb_loaded_version = policydb.policyvers; write_unlock_irq(&policy_rwlock); /* Free the old policydb and SID table. */ policydb_destroy(&oldpolicydb); sidtab_destroy(&oldsidtab); - kfree(oldmap); avc_ss_reset(seqno); selnl_notify_policyload(seqno); @@ -1831,7 +1815,6 @@ int security_load_policy(void *data, size_t len) return 0; err: - kfree(map); sidtab_destroy(&newsidtab); policydb_destroy(&newpolicydb); return rc; @@ -2108,7 +2091,7 @@ int security_get_user_sids(u32 fromsid, } for (i = 0, j = 0; i < mynel; i++) { rc = avc_has_perm_noaudit(fromsid, mysids[i], - SECCLASS_PROCESS, /* kernel value */ + SECCLASS_PROCESS, PROCESS__TRANSITION, AVC_STRICT, NULL); if (!rc) @@ -2136,11 +2119,10 @@ int security_get_user_sids(u32 fromsid, */ int security_genfs_sid(const char *fstype, char *path, - u16 orig_sclass, + u16 sclass, u32 *sid) { int len; - u16 sclass; struct genfs *genfs; struct ocontext *c; int rc = 0, cmp = 0; @@ -2150,8 +2132,6 @@ int security_genfs_sid(const char *fstype, read_lock(&policy_rwlock); - sclass = unmap_class(orig_sclass); - for (genfs = policydb.genfs; genfs; genfs = genfs->next) { cmp = strcmp(fstype, genfs->fstype); if (cmp <= 0) diff --git a/trunk/security/tomoyo/common.c b/trunk/security/tomoyo/common.c index e0d0354008b7..3c8bd8ee0b95 100644 --- a/trunk/security/tomoyo/common.c +++ b/trunk/security/tomoyo/common.c @@ -187,8 +187,6 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, const s8 pattern_type, const s8 end_type, const char *function) { - const char *const start = filename; - bool in_repetition = false; bool contains_pattern = false; unsigned char c; unsigned char d; @@ -214,13 +212,9 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, if (c == '/') goto out; } - while (1) { - c = *filename++; - if (!c) - break; + while ((c = *filename++) != '\0') { if (c == '\\') { - c = *filename++; - switch (c) { + switch ((c = *filename++)) { case '\\': /* "\\" */ continue; case '$': /* "\$" */ @@ -237,22 +231,6 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, break; /* Must not contain pattern */ contains_pattern = true; continue; - case '{': /* "/\{" */ - if (filename - 3 < start || - *(filename - 3) != '/') - break; - if (pattern_type == -1) - break; /* Must not contain pattern */ - contains_pattern = true; - in_repetition = true; - continue; - case '}': /* "\}/" */ - if (*filename != '/') - break; - if (!in_repetition) - break; - in_repetition = false; - continue; case '0': /* "\ooo" */ case '1': case '2': @@ -268,8 +246,6 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, continue; /* pattern is not \000 */ } goto out; - } else if (in_repetition && c == '/') { - goto out; } else if (tomoyo_is_invalid(c)) { goto out; } @@ -278,8 +254,6 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, if (!contains_pattern) goto out; } - if (in_repetition) - goto out; return true; out: printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function, @@ -385,6 +359,33 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) return NULL; } +/** + * tomoyo_path_depth - Evaluate the number of '/' in a string. + * + * @pathname: The string to evaluate. + * + * Returns path depth of the string. + * + * I score 2 for each of the '/' in the @pathname + * and score 1 if the @pathname ends with '/'. + */ +static int tomoyo_path_depth(const char *pathname) +{ + int i = 0; + + if (pathname) { + const char *ep = pathname + strlen(pathname); + if (pathname < ep--) { + if (*ep != '/') + i++; + while (pathname <= ep) + if (*ep-- == '/') + i += 2; + } + } + return i; +} + /** * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. * @@ -443,10 +444,11 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr) ptr->is_dir = len && (name[len - 1] == '/'); ptr->is_patterned = (ptr->const_len < len); ptr->hash = full_name_hash(name, len); + ptr->depth = tomoyo_path_depth(name); } /** - * tomoyo_file_matches_pattern2 - Pattern matching without '/' character + * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character * and "\-" pattern. * * @filename: The start of string to check. @@ -456,10 +458,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr) * * Returns true if @filename matches @pattern, false otherwise. */ -static bool tomoyo_file_matches_pattern2(const char *filename, - const char *filename_end, - const char *pattern, - const char *pattern_end) +static bool tomoyo_file_matches_to_pattern2(const char *filename, + const char *filename_end, + const char *pattern, + const char *pattern_end) { while (filename < filename_end && pattern < pattern_end) { char c; @@ -517,7 +519,7 @@ static bool tomoyo_file_matches_pattern2(const char *filename, case '*': case '@': for (i = 0; i <= filename_end - filename; i++) { - if (tomoyo_file_matches_pattern2( + if (tomoyo_file_matches_to_pattern2( filename + i, filename_end, pattern + 1, pattern_end)) return true; @@ -548,7 +550,7 @@ static bool tomoyo_file_matches_pattern2(const char *filename, j++; } for (i = 1; i <= j; i++) { - if (tomoyo_file_matches_pattern2( + if (tomoyo_file_matches_to_pattern2( filename + i, filename_end, pattern + 1, pattern_end)) return true; @@ -565,7 +567,7 @@ static bool tomoyo_file_matches_pattern2(const char *filename, } /** - * tomoyo_file_matches_pattern - Pattern matching without without '/' character. + * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character. * * @filename: The start of string to check. * @filename_end: The end of string to check. @@ -574,7 +576,7 @@ static bool tomoyo_file_matches_pattern2(const char *filename, * * Returns true if @filename matches @pattern, false otherwise. */ -static bool tomoyo_file_matches_pattern(const char *filename, +static bool tomoyo_file_matches_to_pattern(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end) @@ -587,10 +589,10 @@ static bool tomoyo_file_matches_pattern(const char *filename, /* Split at "\-" pattern. */ if (*pattern++ != '\\' || *pattern++ != '-') continue; - result = tomoyo_file_matches_pattern2(filename, - filename_end, - pattern_start, - pattern - 2); + result = tomoyo_file_matches_to_pattern2(filename, + filename_end, + pattern_start, + pattern - 2); if (first) result = !result; if (result) @@ -598,79 +600,13 @@ static bool tomoyo_file_matches_pattern(const char *filename, first = false; pattern_start = pattern; } - result = tomoyo_file_matches_pattern2(filename, filename_end, - pattern_start, pattern_end); + result = tomoyo_file_matches_to_pattern2(filename, filename_end, + pattern_start, pattern_end); return first ? result : !result; } -/** - * tomoyo_path_matches_pattern2 - Do pathname pattern matching. - * - * @f: The start of string to check. - * @p: The start of pattern to compare. - * - * Returns true if @f matches @p, false otherwise. - */ -static bool tomoyo_path_matches_pattern2(const char *f, const char *p) -{ - const char *f_delimiter; - const char *p_delimiter; - - while (*f && *p) { - f_delimiter = strchr(f, '/'); - if (!f_delimiter) - f_delimiter = f + strlen(f); - p_delimiter = strchr(p, '/'); - if (!p_delimiter) - p_delimiter = p + strlen(p); - if (*p == '\\' && *(p + 1) == '{') - goto recursive; - if (!tomoyo_file_matches_pattern(f, f_delimiter, p, - p_delimiter)) - return false; - f = f_delimiter; - if (*f) - f++; - p = p_delimiter; - if (*p) - p++; - } - /* Ignore trailing "\*" and "\@" in @pattern. */ - while (*p == '\\' && - (*(p + 1) == '*' || *(p + 1) == '@')) - p += 2; - return !*f && !*p; - recursive: - /* - * The "\{" pattern is permitted only after '/' character. - * This guarantees that below "*(p - 1)" is safe. - * Also, the "\}" pattern is permitted only before '/' character - * so that "\{" + "\}" pair will not break the "\-" operator. - */ - if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' || - *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\') - return false; /* Bad pattern. */ - do { - /* Compare current component with pattern. */ - if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2, - p_delimiter - 2)) - break; - /* Proceed to next component. */ - f = f_delimiter; - if (!*f) - break; - f++; - /* Continue comparison. */ - if (tomoyo_path_matches_pattern2(f, p_delimiter + 1)) - return true; - f_delimiter = strchr(f, '/'); - } while (f_delimiter); - return false; /* Not matched. */ -} - /** * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern. - * * @filename: The filename to check. * @pattern: The pattern to compare. * @@ -679,24 +615,24 @@ static bool tomoyo_path_matches_pattern2(const char *f, const char *p) * The following patterns are available. * \\ \ itself. * \ooo Octal representation of a byte. - * \* Zero or more repetitions of characters other than '/'. - * \@ Zero or more repetitions of characters other than '/' or '.'. + * \* More than or equals to 0 character other than '/'. + * \@ More than or equals to 0 character other than '/' or '.'. * \? 1 byte character other than '/'. - * \$ One or more repetitions of decimal digits. + * \$ More than or equals to 1 decimal digit. * \+ 1 decimal digit. - * \X One or more repetitions of hexadecimal digits. + * \X More than or equals to 1 hexadecimal digit. * \x 1 hexadecimal digit. - * \A One or more repetitions of alphabet characters. + * \A More than or equals to 1 alphabet character. * \a 1 alphabet character. - * * \- Subtraction operator. - * - * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/ - * /dir/dir/dir/ ). */ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, const struct tomoyo_path_info *pattern) { + /* + if (!filename || !pattern) + return false; + */ const char *f = filename->name; const char *p = pattern->name; const int len = pattern->const_len; @@ -704,15 +640,37 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, /* If @pattern doesn't contain pattern, I can use strcmp(). */ if (!pattern->is_patterned) return !tomoyo_pathcmp(filename, pattern); - /* Don't compare directory and non-directory. */ - if (filename->is_dir != pattern->is_dir) + /* Dont compare if the number of '/' differs. */ + if (filename->depth != pattern->depth) return false; /* Compare the initial length without patterns. */ if (strncmp(f, p, len)) return false; f += len; p += len; - return tomoyo_path_matches_pattern2(f, p); + /* Main loop. Compare each directory component. */ + while (*f && *p) { + const char *f_delimiter = strchr(f, '/'); + const char *p_delimiter = strchr(p, '/'); + if (!f_delimiter) + f_delimiter = f + strlen(f); + if (!p_delimiter) + p_delimiter = p + strlen(p); + if (!tomoyo_file_matches_to_pattern(f, f_delimiter, + p, p_delimiter)) + return false; + f = f_delimiter; + if (*f) + f++; + p = p_delimiter; + if (*p) + p++; + } + /* Ignore trailing "\*" and "\@" in @pattern. */ + while (*p == '\\' && + (*(p + 1) == '*' || *(p + 1) == '@')) + p += 2; + return !*f && !*p; } /** diff --git a/trunk/security/tomoyo/common.h b/trunk/security/tomoyo/common.h index 92169d29b2db..31df541911f7 100644 --- a/trunk/security/tomoyo/common.h +++ b/trunk/security/tomoyo/common.h @@ -56,6 +56,9 @@ struct tomoyo_page_buffer { * (5) "is_patterned" is a bool which is true if "name" contains wildcard * characters, false otherwise. This allows TOMOYO to use "hash" and * strcmp() for string comparison if "is_patterned" is false. + * (6) "depth" is calculated using the number of "/" characters in "name". + * This allows TOMOYO to avoid comparing two pathnames which never match + * (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$"). */ struct tomoyo_path_info { const char *name; @@ -63,6 +66,7 @@ struct tomoyo_path_info { u16 const_len; /* = tomoyo_const_part_length(name) */ bool is_dir; /* = tomoyo_strendswith(name, "/") */ bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ + u16 depth; /* = tomoyo_path_depth(name) */ }; /* diff --git a/trunk/security/tomoyo/realpath.c b/trunk/security/tomoyo/realpath.c index 917f564cdab1..5f2e33263371 100644 --- a/trunk/security/tomoyo/realpath.c +++ b/trunk/security/tomoyo/realpath.c @@ -13,8 +13,6 @@ #include #include #include -#include - #include "common.h" #include "realpath.h" @@ -265,8 +263,7 @@ static unsigned int tomoyo_quota_for_savename; * table. Frequency of appending strings is very low. So we don't need * large (e.g. 64k) hash size. 256 will be sufficient. */ -#define TOMOYO_HASH_BITS 8 -#define TOMOYO_MAX_HASH (1u<entry.hash && !strcmp(name, ptr->entry.name)) goto out; } @@ -370,7 +365,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name) tomoyo_fill_path_info(&ptr->entry); fmb->ptr += len; fmb->len -= len; - list_add_tail(&ptr->list, head); + list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]); if (fmb->len == 0) { list_del(&fmb->list); kfree(fmb); diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c index 7717e01fc071..64b859925c0b 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -131,7 +131,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link) return err; } - snd_card_set_dev(card, &link->dev); + snd_card_set_dev(card, &handle_to_dev(link)); pdacf->index = i; card_list[i] = card; @@ -142,10 +142,12 @@ static int snd_pdacf_probe(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.NumPorts1 = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT | IRQ_FORCED_PULSE; // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + link->irq.IRQInfo1 = 0 /* | IRQ_LEVEL_ID */; link->irq.Handler = pdacf_interrupt; + link->irq.Instance = pdacf; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; diff --git a/trunk/sound/pcmcia/vx/vxpocket.c b/trunk/sound/pcmcia/vx/vxpocket.c index 7be3b3357045..1492744ad67f 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.c +++ b/trunk/sound/pcmcia/vx/vxpocket.c @@ -161,9 +161,11 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.NumPorts1 = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = &snd_vx_irq_handler; + link->irq.Instance = chip; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -242,7 +244,7 @@ static int vxpocket_config(struct pcmcia_device *link) if (ret) goto failed; - chip->dev = &link->dev; + chip->dev = &handle_to_dev(link); snd_card_set_dev(chip->card, chip->dev); if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)