Commit 42c59208 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (23 commits)
  pcmcia: Fix ide-cs sparse warning
  pcmcia: ide-cs debugging bugfix
  pcmcia: allow for longer CIS firmware files
  pcmcia: cm40x0 cdev lock_kernel() pushdown
  pcmcia: (re)move {pcmcia,pccard}_get_status
  pcmcia: kill IN_CARD_SERVICES
  pcmcia: Remove unused header file code
  pcmcia: remove unused bulkmem.h
  pcmcia: simplify pccard_validate_cis
  pcmcia: carve out ioctl adjust function to pcmcia_ioctl
  pcmcia: irq probe can be done without risking an IRQ storm
  pcmcia: Fix ti12xx_2nd_slot_empty always failing
  pcmcia: check for pointer instead of pointer address
  pcmcia: switch cm4000_cs.c to unlocked_ioctl
  pcmcia: simplify rsrc_nonstatic attributes
  pcmcia: add support CompactFlash PCMCIA support for Blackfin.
  pcmcia: remove version.h
  pcmcia: cs: kill thread_wait
  pcmcia: i82365.c: check request_irq return value
  pcmcia: fix Alchemy warnings
  ...
parents dddec01e 727c6742
......@@ -32,8 +32,9 @@
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/bitrev.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/smp_lock.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
......@@ -1405,11 +1406,11 @@ static void stop_monitor(struct cm4000_dev *dev)
DEBUGP(3, dev, "<- stop_monitor\n");
}
static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct cm4000_dev *dev = filp->private_data;
unsigned int iobase = dev->p_dev->io.BasePort1;
struct inode *inode = filp->f_path.dentry->d_inode;
struct pcmcia_device *link;
int size;
int rc;
......@@ -1426,38 +1427,42 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
iminor(inode), ioctl_names[_IOC_NR(cmd)]);
lock_kernel();
rc = -ENODEV;
link = dev_table[iminor(inode)];
if (!pcmcia_dev_present(link)) {
DEBUGP(4, dev, "DEV_OK false\n");
return -ENODEV;
goto out;
}
if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
DEBUGP(4, dev, "CMM_ABSENT flag set\n");
return -ENODEV;
goto out;
}
rc = EINVAL;
if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) {
DEBUGP(4, dev, "ioctype mismatch\n");
return -EINVAL;
goto out;
}
if (_IOC_NR(cmd) > CM_IOC_MAXNR) {
DEBUGP(4, dev, "iocnr mismatch\n");
return -EINVAL;
goto out;
}
size = _IOC_SIZE(cmd);
rc = 0;
rc = -EFAULT;
DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n",
_IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd);
if (_IOC_DIR(cmd) & _IOC_READ) {
if (!access_ok(VERIFY_WRITE, argp, size))
return -EFAULT;
goto out;
}
if (_IOC_DIR(cmd) & _IOC_WRITE) {
if (!access_ok(VERIFY_READ, argp, size))
return -EFAULT;
goto out;
}
rc = 0;
switch (cmd) {
case CM_IOCGSTATUS:
......@@ -1477,9 +1482,9 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
if (test_bit(IS_BAD_CARD, &dev->flags))
status |= CM_BAD_CARD;
if (copy_to_user(argp, &status, sizeof(int)))
return -EFAULT;
rc = -EFAULT;
}
return 0;
break;
case CM_IOCGATR:
DEBUGP(4, dev, "... in CM_IOCGATR\n");
{
......@@ -1492,25 +1497,29 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|| (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
!= 0)))) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
return -ERESTARTSYS;
rc = -EAGAIN;
else
rc = -ERESTARTSYS;
break;
}
rc = -EFAULT;
if (test_bit(IS_ATR_VALID, &dev->flags) == 0) {
tmp = -1;
if (copy_to_user(&(atreq->atr_len), &tmp,
sizeof(int)))
return -EFAULT;
break;
} else {
if (copy_to_user(atreq->atr, dev->atr,
dev->atr_len))
return -EFAULT;
break;
tmp = dev->atr_len;
if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int)))
return -EFAULT;
break;
}
return 0;
rc = 0;
break;
}
case CM_IOCARDOFF:
......@@ -1538,8 +1547,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|| (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
== 0)))) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
return -ERESTARTSYS;
rc = -EAGAIN;
else
rc = -ERESTARTSYS;
break;
}
/* Set Flags0 = 0x42 */
DEBUGP(4, dev, "Set Flags0=0x42 \n");
......@@ -1554,8 +1565,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|| (test_bit(IS_ATR_VALID, (void *)&dev->flags) !=
0)))) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
return -ERESTARTSYS;
rc = -EAGAIN;
else
rc = -ERESTARTSYS;
break;
}
}
/* release lock */
......@@ -1568,8 +1581,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
struct ptsreq krnptsreq;
if (copy_from_user(&krnptsreq, argp,
sizeof(struct ptsreq)))
return -EFAULT;
sizeof(struct ptsreq))) {
rc = -EFAULT;
break;
}
rc = 0;
DEBUGP(4, dev, "... in CM_IOCSPTS\n");
......@@ -1580,8 +1595,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|| (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
!= 0)))) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
return -ERESTARTSYS;
rc = -EAGAIN;
else
rc = -ERESTARTSYS;
break;
}
/* get IO lock */
if (wait_event_interruptible
......@@ -1590,8 +1607,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|| (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
== 0)))) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
return -ERESTARTSYS;
rc = -EAGAIN;
else
rc = -ERESTARTSYS;
break;
}
if ((rc = set_protocol(dev, &krnptsreq)) != 0) {
......@@ -1604,7 +1623,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
wake_up_interruptible(&dev->ioq);
}
return rc;
break;
#ifdef PCMCIA_DEBUG
case CM_IOSDBGLVL: /* set debug log level */
{
......@@ -1612,18 +1631,20 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
old_pc_debug = pc_debug;
if (copy_from_user(&pc_debug, argp, sizeof(int)))
return -EFAULT;
if (old_pc_debug != pc_debug)
rc = -EFAULT;
else if (old_pc_debug != pc_debug)
DEBUGP(0, dev, "Changed debug log level "
"to %i\n", pc_debug);
}
return rc;
break;
#endif
default:
DEBUGP(4, dev, "... in default (unknown IOCTL code)\n");
return -EINVAL;
rc = -ENOTTY;
}
out:
unlock_kernel();
return rc;
}
static int cmm_open(struct inode *inode, struct file *filp)
......@@ -1631,16 +1652,22 @@ static int cmm_open(struct inode *inode, struct file *filp)
struct cm4000_dev *dev;
struct pcmcia_device *link;
int minor = iminor(inode);
int ret;
if (minor >= CM4000_MAX_DEV)
return -ENODEV;
lock_kernel();
link = dev_table[minor];
if (link == NULL || !pcmcia_dev_present(link))
return -ENODEV;
if (link == NULL || !pcmcia_dev_present(link)) {
ret = -ENODEV;
goto out;
}
if (link->open)
return -EBUSY;
if (link->open) {
ret = -EBUSY;
goto out;
}
dev = link->priv;
filp->private_data = dev;
......@@ -1660,8 +1687,10 @@ static int cmm_open(struct inode *inode, struct file *filp)
* vaild = block until valid (or card
* inserted)
*/
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
if (filp->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
goto out;
}
dev->mdelay = T_50MSEC;
......@@ -1671,7 +1700,10 @@ static int cmm_open(struct inode *inode, struct file *filp)
link->open = 1; /* only one open per device */
DEBUGP(2, dev, "<- cmm_open\n");
return nonseekable_open(inode, filp);
ret = nonseekable_open(inode, filp);
out:
unlock_kernel();
return ret;
}
static int cmm_close(struct inode *inode, struct file *filp)
......@@ -1897,7 +1929,7 @@ static const struct file_operations cm4000_fops = {
.owner = THIS_MODULE,
.read = cmm_read,
.write = cmm_write,
.ioctl = cmm_ioctl,
.unlocked_ioctl = cmm_ioctl,
.open = cmm_open,
.release= cmm_close,
};
......
......@@ -26,6 +26,7 @@
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <asm/io.h>
......@@ -448,23 +449,30 @@ static int cm4040_open(struct inode *inode, struct file *filp)
struct reader_dev *dev;
struct pcmcia_device *link;
int minor = iminor(inode);
int ret;
if (minor >= CM_MAX_DEV)
return -ENODEV;
lock_kernel();
link = dev_table[minor];
if (link == NULL || !pcmcia_dev_present(link))
return -ENODEV;
if (link == NULL || !pcmcia_dev_present(link)) {
ret = -ENODEV;
goto out;
}
if (link->open)
return -EBUSY;
if (link->open) {
ret = -EBUSY;
goto out;
}
dev = link->priv;
filp->private_data = dev;
if (filp->f_flags & O_NONBLOCK) {
DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
return -EAGAIN;
ret = -EAGAIN;
goto out;
}
link->open = 1;
......@@ -473,7 +481,10 @@ static int cm4040_open(struct inode *inode, struct file *filp)
mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
DEBUGP(2, dev, "<- cm4040_open (successfully)\n");
return nonseekable_open(inode, filp);
ret = nonseekable_open(inode, filp);
out:
unlock_kernel();
return ret;
}
static int cm4040_close(struct inode *inode, struct file *filp)
......
......@@ -28,7 +28,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <pcmcia/version.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/device_id.h>
#include <pcmcia/ss.h>
......
......@@ -63,11 +63,11 @@ MODULE_LICENSE("Dual MPL/GPL");
#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
#ifdef PCMCIA_DEBUG
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
#ifdef CONFIG_PCMCIA_DEBUG
INT_MODULE_PARM(pc_debug, 0);
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version =
"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)";
/*static char *version =
"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)";*/
#else
#define DEBUG(n, args...)
#endif
......@@ -375,7 +375,7 @@ static int ide_config(struct pcmcia_device *link)
======================================================================*/
void ide_release(struct pcmcia_device *link)
static void ide_release(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
ide_hwif_t *hwif = info->hwif;
......
......@@ -130,10 +130,6 @@ typedef struct partition_t {
u_int16_t DataUnits;
u_int32_t BlocksPerUnit;
erase_unit_header_t header;
#if 0
region_info_t region;
memory_handle_t handle;
#endif
} partition_t;
/* Partition state flags */
......
......@@ -498,17 +498,14 @@ static int pcmciamtd_config(struct pcmcia_device *link)
int i;
config_info_t t;
static char *probes[] = { "jedec_probe", "cfi_probe" };
cisinfo_t cisinfo;
int new_name = 0;
DEBUG(3, "link=0x%p", link);
DEBUG(2, "Validating CIS");
ret = pcmcia_validate_cis(link, &cisinfo);
ret = pcmcia_validate_cis(link, NULL);
if(ret != CS_SUCCESS) {
cs_error(link, GetTupleData, ret);
} else {
DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains);
}
card_settings(dev, link, &new_name);
......@@ -563,9 +560,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
/* Get write protect status */
CS_CHECK(GetStatus, pcmcia_get_status(link, &status));
DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
status.CardState, (unsigned long)link->win);
DEBUG(2, "window handle = 0x%8.8lx", (unsigned long)link->win);
dev->win_base = ioremap(req.Base, req.Size);
if(!dev->win_base) {
err("ioremap(%lu, %u) failed", req.Base, req.Size);
......
......@@ -263,6 +263,13 @@ config OMAP_CF
Say Y here to support the CompactFlash controller on OMAP.
Note that this doesn't support "True IDE" mode.
config BFIN_CFPCMCIA
tristate "Blackfin CompactFlash PCMCIA Driver"
depends on PCMCIA && BLACKFIN
help
Say Y here to support the CompactFlash PCMCIA driver for Blackfin.
config AT91_CF
tristate "AT91 CompactFlash Controller"
depends on PCMCIA && ARCH_AT91RM9200
......
......@@ -36,6 +36,7 @@ obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
obj-$(CONFIG_OMAP_CF) += omap_cf.o
obj-$(CONFIG_BFIN_CFPCMCIA) += bfin_cf_pcmcia.o
obj-$(CONFIG_AT91_CF) += at91_cf.o
obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
......
......@@ -26,7 +26,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
......@@ -34,9 +33,9 @@
#define AU1000_PCMCIA_IO_SPEED (255)
#define AU1000_PCMCIA_MEM_SPEED (300)
#define AU1X_SOCK0_IO 0xF00000000
#define AU1X_SOCK0_PHYS_ATTR 0xF40000000
#define AU1X_SOCK0_PHYS_MEM 0xF80000000
#define AU1X_SOCK0_IO 0xF00000000ULL
#define AU1X_SOCK0_PHYS_ATTR 0xF40000000ULL
#define AU1X_SOCK0_PHYS_MEM 0xF80000000ULL
/* pseudo 32 bit phys addresses, which get fixed up to the
* real 36 bit address in fixup_bigphys_addr() */
#define AU1X_SOCK0_PSEUDO_PHYS_ATTR 0xF4000000
......@@ -45,16 +44,20 @@
/* pcmcia socket 1 needs external glue logic so the memory map
* differs from board to board.
*/
#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_PB1200)
#define AU1X_SOCK1_IO 0xF08000000
#define AU1X_SOCK1_PHYS_ATTR 0xF48000000
#define AU1X_SOCK1_PHYS_MEM 0xF88000000
#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || \
defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550) || \
defined(CONFIG_MIPS_PB1200)
#define AU1X_SOCK1_IO 0xF08000000ULL
#define AU1X_SOCK1_PHYS_ATTR 0xF48000000ULL
#define AU1X_SOCK1_PHYS_MEM 0xF88000000ULL
#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
#define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8800000
#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || defined(CONFIG_MIPS_DB1200)
#define AU1X_SOCK1_IO 0xF04000000
#define AU1X_SOCK1_PHYS_ATTR 0xF44000000
#define AU1X_SOCK1_PHYS_MEM 0xF84000000
#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550) || \
defined(CONFIG_MIPS_DB1200)
#define AU1X_SOCK1_IO 0xF04000000ULL
#define AU1X_SOCK1_PHYS_ATTR 0xF44000000ULL
#define AU1X_SOCK1_PHYS_MEM 0xF84000000ULL
#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4400000
#define AU1X_SOCK1_PSEUDO_PHYS_MEM 0xF8400000
#endif
......
......@@ -35,7 +35,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/bus_ops.h>
#include "cs_internal.h"
......
......@@ -39,7 +39,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/bus_ops.h>
#include "cs_internal.h"
......
/*
* file: drivers/pcmcia/bfin_cf.c
*
* based on: drivers/pcmcia/omap_cf.c
* omap_cf.c -- OMAP 16xx CompactFlash controller driver
*
* Copyright (c) 2005 David Brownell
* Copyright (c) 2006-2008 Michael Hennerich Analog Devices Inc.
*
* bugs: enter bugs at http://blackfin.uclinux.org/
*
* 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; either version 2, or (at your option)
* any later version.
*
* this program is distributed in the hope that it will be useful,
* but without any warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose. see the
* gnu general public license for more details.
*
* you should have received a copy of the gnu general public license
* along with this program; see the file copying.
* if not, write to the free software foundation,
* 59 temple place - suite 330, boston, ma 02111-1307, usa.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <pcmcia/ss.h>
#include <pcmcia/cisreg.h>
#include <asm/gpio.h>
#define SZ_1K 0x00000400
#define SZ_8K 0x00002000
#define SZ_2K (2 * SZ_1K)
#define POLL_INTERVAL (2 * HZ)
#define CF_ATASEL_ENA 0x20311802 /* Inverts RESET */
#define CF_ATASEL_DIS 0x20311800
#define bfin_cf_present(pfx) (gpio_get_value(pfx))
/*--------------------------------------------------------------------------*/
static const char driver_name[] = "bfin_cf_pcmcia";
struct bfin_cf_socket {
struct pcmcia_socket socket;
struct timer_list timer;
unsigned present:1;
unsigned active:1;
struct platform_device *pdev;
unsigned long phys_cf_io;
unsigned long phys_cf_attr;
u_int irq;
u_short cd_pfx;
};
/*--------------------------------------------------------------------------*/
static int bfin_cf_reset(void)
{
outw(0, CF_ATASEL_ENA);
mdelay(200);
outw(0, CF_ATASEL_DIS);
return 0;
}
static int bfin_cf_ss_init(struct pcmcia_socket *s)
{
return 0;
}
/* the timer is primarily to kick this socket's pccardd */
static void bfin_cf_timer(unsigned long _cf)
{
struct bfin_cf_socket *cf = (void *)_cf;
unsigned short present = bfin_cf_present(cf->cd_pfx);
if (present != cf->present) {
cf->present = present;
dev_dbg(&cf->pdev->dev, ": card %s\n",
present ? "present" : "gone");
pcmcia_parse_events(&cf->socket, SS_DETECT);
}
if (cf->active)
mod_timer(&cf->timer, jiffies + POLL_INTERVAL);
}
static int bfin_cf_get_status(struct pcmcia_socket *s, u_int *sp)
{
struct bfin_cf_socket *cf;
if (!sp)
return -EINVAL;
cf = container_of(s, struct bfin_cf_socket, socket);
if (bfin_cf_present(cf->cd_pfx)) {
*sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
s->irq.AssignedIRQ = 0;
s->pci_irq = cf->irq;
} else
*sp = 0;
return 0;
}
static int
bfin_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
{
struct bfin_cf_socket *cf;
cf = container_of(sock, struct bfin_cf_socket, socket);
switch (s->Vcc) {
case 0:
case 33:
break;
case 50:
break;
default:
return -EINVAL;
}
if (s->flags & SS_RESET) {
disable_irq(cf->irq);
bfin_cf_reset();
enable_irq(cf->irq);
}
dev_dbg(&cf->pdev->dev, ": Vcc %d, io_irq %d, flags %04x csc %04x\n",
s->Vcc, s->io_irq, s->flags, s->csc_mask);
return 0;
}
static int bfin_cf_ss_suspend(struct pcmcia_socket *s)
{
return bfin_cf_set_socket(s, &dead_socket);
}
/* regions are 2K each: mem, attrib, io (and reserved-for-ide) */
static int bfin_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
{
struct bfin_cf_socket *cf;
cf = container_of(s, struct bfin_cf_socket, socket);
io->flags &= MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT;
io->start = cf->phys_cf_io;
io->stop = io->start + SZ_2K - 1;
return 0;
}
static int
bfin_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
{
struct bfin_cf_socket *cf;
if (map->card_start)
return -EINVAL;
cf = container_of(s, struct bfin_cf_socket, socket);
map->static_start = cf->phys_cf_io;
map->flags &= MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT;
if (map->flags & MAP_ATTRIB)
map->static_start = cf->phys_cf_attr;
return 0;
}
static struct pccard_operations bfin_cf_ops = {
.init = bfin_cf_ss_init,
.suspend = bfin_cf_ss_suspend,
.get_status = bfin_cf_get_status,
.set_socket = bfin_cf_set_socket,
.set_io_map = bfin_cf_set_io_map,
.set_mem_map = bfin_cf_set_mem_map,
};
/*--------------------------------------------------------------------------*/
static int __devinit bfin_cf_probe(struct platform_device *pdev)
{
struct bfin_cf_socket *cf;
struct resource *io_mem, *attr_mem;
int irq;
unsigned short cd_pfx;
int status = 0;
dev_info(&pdev->dev, "Blackfin CompactFlash/PCMCIA Socket Driver\n");
irq = platform_get_irq(pdev, 0);
if (!irq)
return -EINVAL;
cd_pfx = platform_get_irq(pdev, 1); /*Card Detect GPIO PIN */
if (gpio_request(cd_pfx, "pcmcia: CD")) {
dev_err(&pdev->dev,
"Failed ro request Card Detect GPIO_%d\n",
cd_pfx);
return -EBUSY;
}
gpio_direction_input(cd_pfx);
cf = kzalloc(sizeof *cf, GFP_KERNEL);
if (!cf) {
gpio_free(cd_pfx);
return -ENOMEM;
}
cf->cd_pfx = cd_pfx;
setup_timer(&cf->timer, bfin_cf_timer, (unsigned long)cf);
cf->pdev = pdev;
platform_set_drvdata(pdev, cf);
cf->irq = irq;
cf->socket.pci_irq = irq;
set_irq_type(irq, IRQF_TRIGGER_LOW);
io_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
attr_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!io_mem || !attr_mem)
goto fail0;
cf->phys_cf_io = io_mem->start;
cf->phys_cf_attr = attr_mem->start;
/* pcmcia layer only remaps "real" memory */
cf->socket.io_offset = (unsigned long)
ioremap(cf->phys_cf_io, SZ_2K);
if (!cf->socket.io_offset)
goto fail0;
dev_err(&pdev->dev, ": on irq %d\n", irq);
dev_dbg(&pdev->dev, ": %s\n",
bfin_cf_present(cf->cd_pfx) ? "present" : "(not present)");
cf->socket.owner = THIS_MODULE;
cf->socket.dev.parent = &pdev->dev;
cf->socket.ops = &bfin_cf_ops;
cf->socket.resource_ops = &pccard_static_ops;
cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
| SS_CAP_MEM_ALIGN;
cf->socket.map_size = SZ_2K;
status = pcmcia_register_socket(&cf->socket);
if (status < 0)
goto fail2;
cf->active = 1;
mod_timer(&cf->timer, jiffies + POLL_INTERVAL);
return 0;
fail2:
iounmap((void __iomem *)cf->socket.io_offset);
release_mem_region(cf->phys_cf_io, SZ_8K);
fail0:
gpio_free(cf->cd_pfx);
kfree(cf);
platform_set_drvdata(pdev, NULL);
return status;
}
static int __devexit bfin_cf_remove(struct platform_device *pdev)
{
struct bfin_cf_socket *cf = platform_get_drvdata(pdev);
gpio_free(cf->cd_pfx);
cf->active = 0;
pcmcia_unregister_socket(&cf->socket);
del_timer_sync(&cf->timer);
iounmap((void __iomem *)cf->socket.io_offset);
release_mem_region(cf->phys_cf_io, SZ_8K);
platform_set_drvdata(pdev, NULL);
kfree(cf);
return 0;
}
static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
{
return pcmcia_socket_dev_suspend(&pdev->dev, mesg);
}
static int bfin_cf_resume(struct platform_device *pdev)
{
return pcmcia_socket_dev_resume(&pdev->dev);
}
static struct platform_driver bfin_cf_driver = {
.driver = {
.name = (char *)driver_name,
.owner = THIS_MODULE,
},
.probe = bfin_cf_probe,
.remove = __devexit_p(bfin_cf_remove),
.suspend = bfin_cf_suspend,
.resume = bfin_cf_resume,
};
static int __init bfin_cf_init(void)
{
return platform_driver_register(&bfin_cf_driver);
}
static void __exit bfin_cf_exit(void)
{
platform_driver_unregister(&bfin_cf_driver);
}
module_init(bfin_cf_init);
module_exit(bfin_cf_exit);
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>")
MODULE_DESCRIPTION("BFIN CF/PCMCIA Driver");
MODULE_LICENSE("GPL");
......@@ -30,11 +30,9 @@
#include <asm/irq.h>
#include <asm/io.h>
#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
......
......@@ -30,7 +30,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
......@@ -1439,10 +1438,11 @@ EXPORT_SYMBOL(pccard_read_tuple);
======================================================================*/
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info)
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *info)
{
tuple_t *tuple;
cisparse_t *p;
unsigned int count = 0;
int ret, reserved, dev_ok = 0, ident_ok = 0;
if (!s)
......@@ -1457,7 +1457,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_
return CS_OUT_OF_RESOURCE;
}
info->Chains = reserved = 0;
count = reserved = 0;
tuple->DesiredTuple = RETURN_FIRST_TUPLE;
tuple->Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, tuple);
......@@ -1482,7 +1482,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_
if (!dev_ok && !ident_ok)
goto done;
for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) {
for (count = 1; count < MAX_TUPLES; count++) {
ret = pccard_get_next_tuple(s, function, tuple);
if (ret != CS_SUCCESS) break;
if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
......@@ -1490,11 +1490,13 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_
((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
reserved++;
}
if ((info->Chains == MAX_TUPLES) || (reserved > 5) ||
((!dev_ok || !ident_ok) && (info->Chains > 10)))
info->Chains = 0;
if ((count) || (reserved > 5) ||
((!dev_ok || !ident_ok) && (count > 10)))
count = 0;
done:
if (info)
*info = count;
kfree(tuple);
kfree(p);
return CS_SUCCESS;
......
......@@ -32,11 +32,9 @@
#include <asm/system.h>
#include <asm/irq.h>
#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
......@@ -238,7 +236,6 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
init_completion(&socket->socket_released);
init_completion(&socket->thread_done);
init_waitqueue_head(&socket->thread_wait);
mutex_init(&socket->skt_mutex);
spin_lock_init(&socket->thread_lock);
......@@ -278,10 +275,9 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket)
cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
if (socket->thread) {
wake_up(&socket->thread_wait);
if (socket->thread)
kthread_stop(socket->thread);
}
release_cis_mem(socket);
/* remove from our own list */
......@@ -635,7 +631,6 @@ static void socket_detect_change(struct pcmcia_socket *skt)
static int pccardd(void *__skt)
{
struct pcmcia_socket *skt = __skt;
DECLARE_WAITQUEUE(wait, current);
int ret;
skt->thread = current;
......@@ -656,7 +651,6 @@ static int pccardd(void *__skt)
if (ret)
dev_warn(&skt->dev, "err %d adding socket attributes\n", ret);
add_wait_queue(&skt->thread_wait, &wait);
complete(&skt->thread_done);
set_freezable();
......@@ -694,8 +688,6 @@ static int pccardd(void *__skt)
/* make sure we are running before we exit */
set_current_state(TASK_RUNNING);
remove_wait_queue(&skt->thread_wait, &wait);
/* remove from the device core */
pccard_sysfs_remove_socket(&skt->dev);
device_unregister(&skt->dev);
......@@ -716,7 +708,7 @@ void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
s->thread_events |= events;
spin_unlock_irqrestore(&s->thread_lock, flags);
wake_up(&s->thread_wait);
wake_up_process(s->thread);
}
} /* pcmcia_parse_events */
EXPORT_SYMBOL(pcmcia_parse_events);
......
......@@ -26,18 +26,6 @@
#define CLIENT_WIN_REQ(i) (0x1<<(i))
#define CLIENT_CARDBUS 0x8000
#define REGION_MAGIC 0xE3C9
typedef struct region_t {
u_short region_magic;
u_short state;
dev_info_t dev_info;
struct pcmcia_device *mtd;
u_int MediaID;
region_info_t info;
} region_t;
#define REGION_STALE 0x01
/* Each card function gets one of these guys */
typedef struct config_t {
struct kref ref;
......@@ -130,7 +118,6 @@ extern struct list_head pcmcia_socket_list;
int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
int pccard_reset_card(struct pcmcia_socket *skt);
int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status);
struct pcmcia_callback{
......
......@@ -25,7 +25,6 @@
#include <linux/kref.h>
#include <linux/dma-mapping.h>
#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
......@@ -741,9 +740,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
static int pcmcia_card_add(struct pcmcia_socket *s)
{
cisinfo_t cisinfo;
cistpl_longlink_mfc_t mfc;
unsigned int no_funcs, i;
unsigned int no_funcs, i, no_chains;
int ret = 0;
if (!(s->resource_setup_done)) {
......@@ -757,8 +755,8 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
return -EAGAIN; /* try again, but later... */
}
ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo);
if (ret || !cisinfo.Chains) {
ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains);
if (ret || !no_chains) {
ds_dbg(0, "invalid CIS or invalid resources\n");
return -ENODEV;
}
......@@ -852,7 +850,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
{
struct pcmcia_socket *s = dev->socket;
const struct firmware *fw;
char path[20];
char path[FIRMWARE_NAME_MAX];
int ret = -ENOMEM;
int no_funcs;
int old_funcs;
......@@ -864,7 +862,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
ds_dbg(1, "trying to load CIS file %s\n", filename);
if (strlen(filename) > 14) {
if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) {
printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n",
filename);
return -EINVAL;
......
/*
* $Id: hd64465_ss.c,v 1.7 2003/07/06 14:42:50 lethal Exp $
*
* Device driver for the PCMCIA controller module of the
* Hitachi HD64465 handheld companion chip.
*
......@@ -48,7 +46,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include "cs_internal.h"
#define MODNAME "hd64465_ss"
......
......@@ -5,8 +5,6 @@
*
* Author: Arjan Van De Ven <arjanv@redhat.com>
* Loosly based on i82365.c from the pcmcia-cs package
*
* $Id: i82092aa.c,v 1.2 2001/10/23 14:43:34 arjanv Exp $
*/
#include <linux/kernel.h>
......
......@@ -3,8 +3,6 @@
#include <linux/interrupt.h>
/* $Id: i82092aa.h,v 1.1.1.1 2001/09/19 14:53:15 dwmw2 Exp $ */
/* Debuging defines */
#ifdef NOTRACE
#define enter(x) printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
......
......@@ -1263,7 +1263,7 @@ static int __init init_i82365(void)
ret = driver_register(&i82365_driver);
if (ret)
return ret;
goto err_out;
i82365_device = platform_device_alloc("i82365", 0);
if (i82365_device) {
......@@ -1273,10 +1273,8 @@ static int __init init_i82365(void)
} else
ret = -ENOMEM;
if (ret) {
driver_unregister(&i82365_driver);
return ret;
}
if (ret)
goto err_driver_unregister;
printk(KERN_INFO "Intel ISA PCIC probe: ");
sockets = 0;
......@@ -1285,16 +1283,17 @@ static int __init init_i82365(void)
if (sockets == 0) {
printk("not found.\n");
platform_device_unregister(i82365_device);
release_region(i365_base, 2);
driver_unregister(&i82365_driver);
return -ENODEV;
ret = -ENODEV;
goto err_dev_unregister;
}
/* Set up interrupt handler(s) */
if (grab_irq != 0)
request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
ret = request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
if (ret)
goto err_socket_release;
/* register sockets with the pcmcia core */
for (i = 0; i < sockets; i++) {
socket[i].socket.dev.parent = &i82365_device->dev;
......@@ -1324,7 +1323,23 @@ static int __init init_i82365(void)
}
return 0;
err_socket_release:
for (i = 0; i < sockets; i++) {
/* Turn off all interrupt sources! */
i365_set(i, I365_CSCINT, 0);
release_region(socket[i].ioaddr, 2);
}
err_dev_unregister:
platform_device_unregister(i82365_device);
release_region(i365_base, 2);
#ifdef CONFIG_PNP
if (i82365_pnpdev)
pnp_disable_dev(i82365_pnpdev);
#endif
err_driver_unregister:
driver_unregister(&i82365_driver);
err_out:
return ret;
} /* init_i82365 */
static void __exit exit_i82365(void)
......
/*
* m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
*
* (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
* (C) 1999-2000 Magnus Damm <damm@opensource.se>
* (C) 2001-2002 Montavista Software, Inc.
* <mlocke@mvista.com>
*
......@@ -60,7 +60,6 @@
#include <asm/of_device.h>
#include <asm/of_platform.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
......
......@@ -29,10 +29,10 @@
#include <linux/pci.h>
#include <linux/workqueue.h>
#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
#include <pcmcia/ss.h>
......@@ -138,6 +138,154 @@ static int proc_read_drivers(char *buf, char **start, off_t pos,
}
#endif
#ifdef CONFIG_PCMCIA_PROBE
static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
{
int irq;
u32 mask;
irq = adj->resource.irq.IRQ;
if ((irq < 0) || (irq > 15))
return CS_BAD_IRQ;
if (adj->Action != REMOVE_MANAGED_RESOURCE)
return 0;
mask = 1 << irq;
if (!(s->irq_mask & mask))
return 0;
s->irq_mask &= ~mask;
return 0;
}
#else
static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
return CS_SUCCESS;
}
#endif
static int pcmcia_adjust_resource_info(adjust_t *adj)
{
struct pcmcia_socket *s;
int ret = CS_UNSUPPORTED_FUNCTION;
unsigned long flags;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
if (adj->Resource == RES_IRQ)
ret = adjust_irq(s, adj);
else if (s->resource_ops->add_io) {
unsigned long begin, end;
/* you can't use the old interface if the new
* one was used before */
spin_lock_irqsave(&s->lock, flags);
if ((s->resource_setup_new) &&
!(s->resource_setup_old)) {
spin_unlock_irqrestore(&s->lock, flags);
continue;
} else if (!(s->resource_setup_old))
s->resource_setup_old = 1;
spin_unlock_irqrestore(&s->lock, flags);
switch (adj->Resource) {
case RES_MEMORY_RANGE:
begin = adj->resource.memory.Base;
end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
if (s->resource_ops->add_mem)
ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
case RES_IO_RANGE:
begin = adj->resource.io.BasePort;
end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
if (s->resource_ops->add_io)
ret = s->resource_ops->add_io(s, adj->Action, begin, end);
}
if (!ret) {
/* as there's no way we know this is the
* last call to adjust_resource_info, we
* always need to assume this is the latest
* one... */
spin_lock_irqsave(&s->lock, flags);
s->resource_setup_done = 1;
spin_unlock_irqrestore(&s->lock, flags);
}
}
}
up_read(&pcmcia_socket_list_rwsem);
return (ret);
}
/** pccard_get_status
*
* Get the current socket state bits. We don't support the latched
* SocketState yet: I haven't seen any point for it.
*/
static int pccard_get_status(struct pcmcia_socket *s,
struct pcmcia_device *p_dev,
cs_status_t *status)
{
config_t *c;
int val;
s->ops->get_status(s, &val);
status->CardState = status->SocketState = 0;
status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
if (s->state & SOCKET_SUSPEND)
status->CardState |= CS_EVENT_PM_SUSPEND;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
c = (p_dev) ? p_dev->function_config : NULL;
if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
u_char reg;
if (c->CardValues & PRESENT_PIN_REPLACE) {
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
status->CardState |=
(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
status->CardState |=
(reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
status->CardState |=
(reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
status->CardState |=
(reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
} else {
/* No PRR? Then assume we're always ready */
status->CardState |= CS_EVENT_READY_CHANGE;
}
if (c->CardValues & PRESENT_EXT_STATUS) {
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
status->CardState |=
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
}
return CS_SUCCESS;
}
status->CardState |=
(val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
status->CardState |=
(val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
status->CardState |=
(val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
status->CardState |=
(val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
return CS_SUCCESS;
} /* pccard_get_status */
/*======================================================================
These manage a ring buffer of events pending for one user process
......@@ -546,8 +694,6 @@ static u_int ds_poll(struct file *file, poll_table *wait)
/*====================================================================*/
extern int pcmcia_adjust_resource_info(adjust_t *adj);
static int ds_ioctl(struct inode * inode, struct file * file,
u_int cmd, u_long arg)
{
......@@ -649,7 +795,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
mutex_lock(&s->skt_mutex);
pcmcia_validate_mem(s);
mutex_unlock(&s->skt_mutex);
ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
break;
case DS_SUSPEND_CARD:
ret = pcmcia_suspend_card(s);
......
......@@ -21,11 +21,9 @@
#include <linux/pci.h>
#include <linux/device.h>
#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
......@@ -311,74 +309,6 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
EXPORT_SYMBOL(pcmcia_get_window);
/** pccard_get_status
*
* Get the current socket state bits. We don't support the latched
* SocketState yet: I haven't seen any point for it.
*/
int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev,
cs_status_t *status)
{
config_t *c;
int val;
s->ops->get_status(s, &val);
status->CardState = status->SocketState = 0;
status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
if (s->state & SOCKET_SUSPEND)
status->CardState |= CS_EVENT_PM_SUSPEND;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
c = (p_dev) ? p_dev->function_config : NULL;
if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
u_char reg;
if (c->CardValues & PRESENT_PIN_REPLACE) {
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
status->CardState |=
(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
status->CardState |=
(reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
status->CardState |=
(reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
status->CardState |=
(reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
} else {
/* No PRR? Then assume we're always ready */
status->CardState |= CS_EVENT_READY_CHANGE;
}
if (c->CardValues & PRESENT_EXT_STATUS) {
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
status->CardState |=
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
}
return CS_SUCCESS;
}
status->CardState |=
(val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
status->CardState |=
(val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
status->CardState |=
(val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
status->CardState |=
(val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
return CS_SUCCESS;
} /* pccard_get_status */
int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status)
{
return pccard_get_status(p_dev->socket, p_dev, status);
}
EXPORT_SYMBOL(pcmcia_get_status);
/** pcmcia_get_mem_page
*
* Change the card address of an already open memory window.
......@@ -812,6 +742,15 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
type = IRQF_SHARED;
#ifdef CONFIG_PCMCIA_PROBE
#ifdef IRQ_NOAUTOEN
/* if the underlying IRQ infrastructure allows for it, only allocate
* the IRQ, but do not enable it
*/
if (!(req->Attributes & IRQ_HANDLE_PRESENT))
type |= IRQ_NOAUTOEN;
#endif /* IRQ_NOAUTOEN */
if (s->irq.AssignedIRQ != 0) {
/* If the interrupt is already assigned, it must be the same */
irq = s->irq.AssignedIRQ;
......@@ -966,7 +905,7 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
pcmcia_release_configuration(p_dev);
pcmcia_release_io(p_dev, &p_dev->io);
pcmcia_release_irq(p_dev, &p_dev->irq);
if (&p_dev->win)
if (p_dev->win)
pcmcia_release_window(p_dev->win);
}
EXPORT_SYMBOL(pcmcia_disable_device);
......@@ -33,7 +33,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
......
......@@ -21,86 +21,6 @@
#include "cs_internal.h"
#ifdef CONFIG_PCMCIA_IOCTL
#ifdef CONFIG_PCMCIA_PROBE
static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
{
int irq;
u32 mask;
irq = adj->resource.irq.IRQ;
if ((irq < 0) || (irq > 15))
return CS_BAD_IRQ;
if (adj->Action != REMOVE_MANAGED_RESOURCE)
return 0;
mask = 1 << irq;
if (!(s->irq_mask & mask))
return 0;
s->irq_mask &= ~mask;
return 0;
}
#else
static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
return CS_SUCCESS;
}
#endif
int pcmcia_adjust_resource_info(adjust_t *adj)
{
struct pcmcia_socket *s;
int ret = CS_UNSUPPORTED_FUNCTION;
unsigned long flags;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
if (adj->Resource == RES_IRQ)
ret = adjust_irq(s, adj);
else if (s->resource_ops->adjust_resource) {
/* you can't use the old interface if the new
* one was used before */
spin_lock_irqsave(&s->lock, flags);
if ((s->resource_setup_new) &&
!(s->resource_setup_old)) {
spin_unlock_irqrestore(&s->lock, flags);
continue;
} else if (!(s->resource_setup_old))
s->resource_setup_old = 1;
spin_unlock_irqrestore(&s->lock, flags);
ret = s->resource_ops->adjust_resource(s, adj);
if (!ret) {
/* as there's no way we know this is the
* last call to adjust_resource_info, we
* always need to assume this is the latest
* one... */
spin_lock_irqsave(&s->lock, flags);
s->resource_setup_done = 1;
spin_unlock_irqrestore(&s->lock, flags);
}
}
}
up_read(&pcmcia_socket_list_rwsem);
return (ret);
}
EXPORT_SYMBOL(pcmcia_adjust_resource_info);
#endif
int pcmcia_validate_mem(struct pcmcia_socket *s)
{
if (s->resource_ops->validate_mem)
......@@ -164,7 +84,8 @@ struct pccard_resource_ops pccard_static_ops = {
.adjust_io_region = NULL,
.find_io = NULL,
.find_mem = NULL,
.adjust_resource = NULL,
.add_io = NULL,
.add_mem = NULL,
.init = static_init,
.exit = NULL,
};
......@@ -264,7 +185,8 @@ struct pccard_resource_ops pccard_iodyn_ops = {
.adjust_io_region = iodyn_adjust_io_region,
.find_io = iodyn_find_io_region,
.find_mem = NULL,
.adjust_resource = NULL,
.add_io = NULL,
.add_mem = NULL,
.init = static_init,
.exit = NULL,
};
......
......@@ -31,7 +31,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
......@@ -261,21 +260,22 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
======================================================================*/
/* Validation function for cards with a valid CIS */
static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
static int readable(struct pcmcia_socket *s, struct resource *res,
unsigned int *count)
{
int ret = -1;
s->cis_mem.res = res;
s->cis_virt = ioremap(res->start, s->map_size);
if (s->cis_virt) {
ret = pccard_validate_cis(s, BIND_FN_ALL, info);
ret = pccard_validate_cis(s, BIND_FN_ALL, count);
/* invalidate mapping and CIS cache */
iounmap(s->cis_virt);
s->cis_virt = NULL;
destroy_cis_cache(s);
}
s->cis_mem.res = NULL;
if ((ret != 0) || (info->Chains == 0))
if ((ret != 0) || (count == 0))
return 0;
return 1;
}
......@@ -316,7 +316,7 @@ static int
cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
{
struct resource *res1, *res2;
cisinfo_t info1, info2;
unsigned int info1, info2;
int ret = 0;
res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
......@@ -330,7 +330,7 @@ cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
free_region(res2);
free_region(res1);
return (ret == 2) && (info1.Chains == info2.Chains);
return (ret == 2) && (info1 == info2);
}
static int
......@@ -766,21 +766,6 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
}
static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
{
unsigned long end;
switch (adj->Resource) {
case RES_MEMORY_RANGE:
end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);
case RES_IO_RANGE:
end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);
}
return CS_UNSUPPORTED_FUNCTION;
}
#ifdef CONFIG_PCI
static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
{
......@@ -889,7 +874,8 @@ struct pccard_resource_ops pccard_nonstatic_ops = {
.adjust_io_region = nonstatic_adjust_io_region,
.find_io = nonstatic_find_io_region,
.find_mem = nonstatic_find_mem_region,
.adjust_resource = nonstatic_adjust_resource_info,
.add_io = adjust_io,
.add_mem = adjust_memory,
.init = nonstatic_init,
.exit = nonstatic_release_resource_db,
};
......@@ -1008,41 +994,34 @@ static ssize_t store_mem_db(struct device *dev,
}
static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
static struct device_attribute *pccard_rsrc_attributes[] = {
&dev_attr_available_resources_io,
&dev_attr_available_resources_mem,
static struct attribute *pccard_rsrc_attributes[] = {
&dev_attr_available_resources_io.attr,
&dev_attr_available_resources_mem.attr,
NULL,
};
static const struct attribute_group rsrc_attributes = {
.attrs = pccard_rsrc_attributes,
};
static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
struct class_interface *class_intf)
{
struct pcmcia_socket *s = dev_get_drvdata(dev);
struct device_attribute **attr;
int ret = 0;
if (s->resource_ops != &pccard_nonstatic_ops)
return 0;
for (attr = pccard_rsrc_attributes; *attr; attr++) {
ret = device_create_file(dev, *attr);
if (ret)
break;
}
return ret;
return sysfs_create_group(&dev->kobj, &rsrc_attributes);
}
static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
struct class_interface *class_intf)
{
struct pcmcia_socket *s = dev_get_drvdata(dev);
struct device_attribute **attr;
if (s->resource_ops != &pccard_nonstatic_ops)
return;
for (attr = pccard_rsrc_attributes; *attr; attr++)
device_remove_file(dev, *attr);
sysfs_remove_group(&dev->kobj, &rsrc_attributes);
}
static struct class_interface pccard_rsrc_interface __refdata = {
......
......@@ -14,7 +14,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
......
......@@ -27,11 +27,9 @@
#include <asm/system.h>
#include <asm/irq.h>
#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
......@@ -293,7 +291,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
count = 0;
else {
struct pcmcia_socket *s;
cisinfo_t cisinfo;
unsigned int chains;
if (off + count > size)
count = size - off;
......@@ -302,9 +300,9 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
if (!(s->state & SOCKET_PRESENT))
return -ENODEV;
if (pccard_validate_cis(s, BIND_FN_ALL, &cisinfo))
if (pccard_validate_cis(s, BIND_FN_ALL, &chains))
return -EIO;
if (!cisinfo.Chains)
if (!chains)
return -ENODATA;
count = pccard_extract_cis(s, buf, off, count);
......
......@@ -155,7 +155,7 @@
#define ENE_TEST_C9_TLTENABLE 0x02
#define ENE_TEST_C9_PFENABLE_F0 0x04
#define ENE_TEST_C9_PFENABLE_F1 0x08
#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F0)
#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F1)
#define ENE_TEST_C9_WPDISALBLE_F0 0x40
#define ENE_TEST_C9_WPDISALBLE_F1 0x80
#define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1)
......@@ -692,7 +692,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
goto out;
/* check state */
yenta_get_status(&socket->socket, &state);
yenta_get_status(&slot2->socket, &state);
if (state & SS_DETECT) {
ret = 0;
goto out;
......
/*
* bulkmem.h -- Definitions for bulk memory services
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
*/
#ifndef _LINUX_BULKMEM_H
#define _LINUX_BULKMEM_H
/* For GetFirstRegion and GetNextRegion */
typedef struct region_info_t {
u_int Attributes;
u_int CardOffset;
u_int RegionSize;
u_int AccessSpeed;
u_int BlockSize;
u_int PartMultiple;
u_char JedecMfr, JedecInfo;
memory_handle_t next;
} region_info_t;
#define REGION_TYPE 0x0001
#define REGION_TYPE_CM 0x0000
#define REGION_TYPE_AM 0x0001
#define REGION_PREFETCH 0x0008
#define REGION_CACHEABLE 0x0010
#define REGION_BAR_MASK 0xe000
#define REGION_BAR_SHIFT 13
int pcmcia_get_first_region(struct pcmcia_device *handle, region_info_t *rgn);
int pcmcia_get_next_region(struct pcmcia_device *handle, region_info_t *rgn);
#endif /* _LINUX_BULKMEM_H */
......@@ -595,7 +595,7 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse);
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info);
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *count);
/* ... but use these wrappers instead */
#define pcmcia_get_first_tuple(p_dev, tuple) \
......
......@@ -373,9 +373,6 @@ struct pcmcia_socket;
int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg);
int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);
int pcmcia_get_first_window(window_handle_t *win, win_req_t *req);
int pcmcia_get_next_window(window_handle_t *win, win_req_t *req);
int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status);
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);
......
......@@ -21,7 +21,8 @@
#include <sys/types.h>
#endif
#if defined(__arm__) || defined(__mips__) || defined(__avr32__)
#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \
defined(__bfin__)
/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
typedef u_int ioaddr_t;
#else
......@@ -33,9 +34,6 @@ typedef u_int event_t;
typedef u_char cisdata_t;
typedef u_short page_t;
struct pcmcia_device;
typedef struct pcmcia_device *client_handle_t;
struct window_t;
typedef struct window_t *window_handle_t;
......
......@@ -20,7 +20,6 @@
#include <linux/mod_devicetable.h>
#endif
#include <pcmcia/bulkmem.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/device_id.h>
......@@ -51,6 +50,24 @@ typedef struct mtd_info_t {
u_int CardOffset;
} mtd_info_t;
typedef struct region_info_t {
u_int Attributes;
u_int CardOffset;
u_int RegionSize;
u_int AccessSpeed;
u_int BlockSize;
u_int PartMultiple;
u_char JedecMfr, JedecInfo;
memory_handle_t next;
} region_info_t;
#define REGION_TYPE 0x0001
#define REGION_TYPE_CM 0x0000
#define REGION_TYPE_AM 0x0001
#define REGION_PREFETCH 0x0008
#define REGION_CACHEABLE 0x0010
#define REGION_BAR_MASK 0xe000
#define REGION_BAR_SHIFT 13
typedef union ds_ioctl_arg_t {
adjust_t adjust;
config_info_t config;
......
......@@ -21,7 +21,6 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
#ifdef CONFIG_CARDBUS
#include <linux/pci.h>
#endif
......@@ -136,8 +135,14 @@ struct pccard_resource_ops {
struct resource* (*find_mem) (unsigned long base, unsigned long num,
unsigned long align, int low,
struct pcmcia_socket *s);
int (*adjust_resource) (struct pcmcia_socket *s,
adjust_t *adj);
int (*add_io) (struct pcmcia_socket *s,
unsigned int action,
unsigned long r_start,
unsigned long r_end);
int (*add_mem) (struct pcmcia_socket *s,
unsigned int action,
unsigned long r_start,
unsigned long r_end);
int (*init) (struct pcmcia_socket *s);
void (*exit) (struct pcmcia_socket *s);
};
......@@ -245,7 +250,6 @@ struct pcmcia_socket {
struct task_struct *thread;
struct completion thread_done;
wait_queue_head_t thread_wait;
spinlock_t thread_lock; /* protects thread_events */
unsigned int thread_events;
......
/* version.h 1.94 2000/10/03 17:55:48 (David Hinds) */
/* This file will be removed, please don't include it */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment