Commit 30be2b69 authored by Jeff Garzik's avatar Jeff Garzik

Merge pobox.com:/garz/repo/netdev-2.6/smc91x

into pobox.com:/garz/repo/net-drivers-2.6
parents 56ca2948 955bd9bb
......@@ -138,6 +138,7 @@ static struct platform_device sa1111_device = {
static struct resource smc91x_resources[] = {
[0] = {
.name = "smc91x-regs",
.start = 0x0c000000,
.end = 0x0c0fffff,
.flags = IORESOURCE_MEM,
......@@ -148,6 +149,7 @@ static struct resource smc91x_resources[] = {
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = "smc91x-attrib",
.start = 0x0e000000,
.end = 0x0e0fffff,
.flags = IORESOURCE_MEM,
......
......@@ -266,6 +266,7 @@ static struct platform_device sa1111_device = {
static struct resource smc91x_resources[] = {
[0] = {
.name = "smc91x-regs",
.start = SA1100_CS3_PHYS,
.end = SA1100_CS3_PHYS + 0x01ffffff,
.flags = IORESOURCE_MEM,
......@@ -276,6 +277,7 @@ static struct resource smc91x_resources[] = {
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = "smc91x-attrib",
.start = SA1100_CS3_PHYS + 0x02000000,
.end = SA1100_CS3_PHYS + 0x03ffffff,
.flags = IORESOURCE_MEM,
......
......@@ -210,10 +210,15 @@ struct smc_local {
spinlock_t lock;
#ifdef SMC_CAN_USE_DATACS
u32 __iomem *datacs;
#endif
#ifdef SMC_USE_PXA_DMA
/* DMA needs the physical address of the chip */
u_long physaddr;
#endif
void __iomem *base;
};
#if SMC_DEBUG > 0
......@@ -307,8 +312,8 @@ static void PRINT_PKT(u_char *buf, int length)
*/
static void smc_reset(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int ctl, cfg;
DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
......@@ -399,8 +404,8 @@ static void smc_reset(struct net_device *dev)
*/
static void smc_enable(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
int mask;
DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
......@@ -433,8 +438,8 @@ static void smc_enable(struct net_device *dev)
*/
static void smc_shutdown(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
......@@ -462,7 +467,7 @@ static void smc_shutdown(struct net_device *dev)
static inline void smc_rcv(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
unsigned int packet_number, status, packet_len;
DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
......@@ -483,7 +488,19 @@ static inline void smc_rcv(struct net_device *dev)
dev->name, packet_number, status,
packet_len, packet_len);
if (unlikely(status & RS_ERRORS)) {
back:
if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) {
/* accept VLAN packets */
status &= ~RS_TOOLONG;
goto back;
}
if (packet_len < 6) {
/* bloody hardware */
printk(KERN_ERR "%s: fubar (rxlen %u status %x\n",
dev->name, packet_len, status);
status |= RS_TOOSHORT;
}
SMC_WAIT_MMU_BUSY();
SMC_SET_MMU_CMD(MC_RELEASE);
lp->stats.rx_errors++;
......@@ -508,7 +525,7 @@ static inline void smc_rcv(struct net_device *dev)
* (2 bytes, possibly containing the payload odd byte).
* Furthermore, we add 2 bytes to allow rounding up to
* multiple of 4 bytes on 32 bit buses.
* Ence packet_len - 6 + 2 + 2 + 2.
* Hence packet_len - 6 + 2 + 2 + 2.
*/
skb = dev_alloc_skb(packet_len);
if (unlikely(skb == NULL)) {
......@@ -596,7 +613,7 @@ static void smc_hardware_send_pkt(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
struct sk_buff *skb;
unsigned int packet_no, len;
unsigned char *buf;
......@@ -680,7 +697,7 @@ done: if (!THROTTLE_TX_PKTS)
static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
unsigned int numPages, poll_count, status;
DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
......@@ -752,8 +769,8 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static void smc_tx(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int saved_packet, packet_no, tx_status, pkt_len;
DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
......@@ -809,7 +826,8 @@ static void smc_tx(struct net_device *dev)
static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int mii_reg, mask;
mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO);
......@@ -830,7 +848,8 @@ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
static unsigned int smc_mii_in(struct net_device *dev, int bits)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int mii_reg, mask, val;
mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO);
......@@ -854,7 +873,8 @@ static unsigned int smc_mii_in(struct net_device *dev, int bits)
*/
static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int phydata;
SMC_SELECT_BANK(3);
......@@ -884,7 +904,8 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
int phydata)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
SMC_SELECT_BANK(3);
......@@ -946,7 +967,7 @@ static void smc_phy_detect(struct net_device *dev)
static int smc_phy_fixed(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
int phyaddr = lp->mii.phy_id;
int bmcr, cfg1;
......@@ -1017,13 +1038,29 @@ static int smc_phy_reset(struct net_device *dev, int phy)
/*
* smc_phy_powerdown - powerdown phy
* @dev: net device
* @phy: phy address
*
* Power down the specified PHY
*/
static void smc_phy_powerdown(struct net_device *dev, int phy)
static void smc_phy_powerdown(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
unsigned int bmcr;
int phy = lp->mii.phy_id;
if (lp->phy_type == 0)
return;
/* We need to ensure that no calls to smc_phy_configure are
pending.
flush_scheduled_work() cannot be called because we are
running with the netlink semaphore held (from
devinet_ioctl()) and the pending work queue contains
linkwatch_event() (scheduled by netif_carrier_off()
above). linkwatch_event() also wants the netlink semaphore.
*/
while(lp->work_pending)
schedule();
bmcr = smc_phy_read(dev, phy, MII_BMCR);
smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
......@@ -1040,7 +1077,7 @@ static void smc_phy_powerdown(struct net_device *dev, int phy)
static void smc_phy_check_media(struct net_device *dev, int init)
{
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
/* duplex state has changed */
......@@ -1068,7 +1105,7 @@ static void smc_phy_configure(void *data)
{
struct net_device *dev = data;
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
int phyaddr = lp->mii.phy_id;
int my_phy_caps; /* My PHY capabilities */
int my_ad_caps; /* My Advertised capabilities */
......@@ -1193,7 +1230,7 @@ static void smc_phy_interrupt(struct net_device *dev)
static void smc_10bt_check_media(struct net_device *dev, int init)
{
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
unsigned int old_carrier, new_carrier;
old_carrier = netif_carrier_ok(dev) ? 1 : 0;
......@@ -1216,7 +1253,8 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
static void smc_eph_interrupt(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int ctl;
smc_10bt_check_media(dev, 0);
......@@ -1235,8 +1273,8 @@ static void smc_eph_interrupt(struct net_device *dev)
static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
unsigned long ioaddr = dev->base_addr;
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
int status, mask, timeout, card_stats;
int saved_pointer;
......@@ -1350,7 +1388,7 @@ static void smc_poll_controller(struct net_device *dev)
static void smc_timeout(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
int status, mask, meminfo, fifo;
DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
......@@ -1394,7 +1432,7 @@ static void smc_timeout(struct net_device *dev)
static void smc_set_multicast_list(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
void __iomem *ioaddr = lp->base;
unsigned char multicast_table[8];
int update_multicast = 0;
......@@ -1561,21 +1599,7 @@ static int smc_close(struct net_device *dev)
/* clear everything */
smc_shutdown(dev);
if (lp->phy_type != 0) {
/* We need to ensure that no calls to
smc_phy_configure are pending.
flush_scheduled_work() cannot be called because we
are running with the netlink semaphore held (from
devinet_ioctl()) and the pending work queue
contains linkwatch_event() (scheduled by
netif_carrier_off() above). linkwatch_event() also
wants the netlink semaphore.
*/
while(lp->work_pending)
schedule();
smc_phy_powerdown(dev, lp->mii.phy_id);
}
smc_phy_powerdown(dev);
if (lp->pending_tx_skb) {
dev_kfree_skb(lp->pending_tx_skb);
......@@ -1723,7 +1747,7 @@ static struct ethtool_ops smc_ethtool_ops = {
* I just deleted auto_irq.c, since it was never built...
* --jgarzik
*/
static int __init smc_findirq(unsigned long ioaddr)
static int __init smc_findirq(void __iomem *ioaddr)
{
int timeout = 20;
unsigned long cookie;
......@@ -1796,7 +1820,7 @@ static int __init smc_findirq(unsigned long ioaddr)
* o actually GRAB the irq.
* o GRAB the region
*/
static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
{
struct smc_local *lp = netdev_priv(dev);
static int version_printed = 0;
......@@ -1813,7 +1837,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
if ((val & 0xFF) == 0x33) {
printk(KERN_WARNING
"%s: Detected possible byte-swapped interface"
" at IOADDR 0x%lx\n", CARDNAME, ioaddr);
" at IOADDR %p\n", CARDNAME, ioaddr);
}
retval = -ENODEV;
goto err_out;
......@@ -1839,8 +1863,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
SMC_SELECT_BANK(1);
val = SMC_GET_BASE();
val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
if ((ioaddr & ((PAGE_SIZE-1)<<SMC_IO_SHIFT)) != val) {
printk("%s: IOADDR %lx doesn't match configuration (%x).\n",
if (((unsigned long)ioaddr & ((PAGE_SIZE-1)<<SMC_IO_SHIFT)) != val) { /*XXX: WTF? */
printk("%s: IOADDR %p doesn't match configuration (%x).\n",
CARDNAME, ioaddr, val);
}
......@@ -1855,7 +1879,7 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
version_string = chip_ids[ (revision_register >> 4) & 0xF];
if (!version_string || (revision_register & 0xff00) != 0x3300) {
/* I don't recognize this chip, so... */
printk("%s: IO 0x%lx: Unrecognized revision register 0x%04x"
printk("%s: IO %p: Unrecognized revision register 0x%04x"
", Contact author.\n", CARDNAME,
ioaddr, revision_register);
......@@ -1868,7 +1892,8 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
printk("%s", version);
/* fill in some of the fields */
dev->base_addr = ioaddr;
dev->base_addr = (unsigned long)ioaddr;
lp->base = ioaddr;
lp->version = revision_register & 0xff;
spin_lock_init(&lp->lock);
......@@ -1974,9 +1999,9 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
retval = register_netdev(dev);
if (retval == 0) {
/* now, print out the card info, in a short format.. */
printk("%s: %s (rev %d) at %#lx IRQ %d",
printk("%s: %s (rev %d) at %p IRQ %d",
dev->name, version_string, revision_register & 0x0f,
dev->base_addr, dev->irq);
lp->base, dev->irq);
if (dev->dma != (unsigned char)-1)
printk(" DMA %d", dev->dma);
......@@ -2012,16 +2037,21 @@ static int __init smc_probe(struct net_device *dev, unsigned long ioaddr)
return retval;
}
static int smc_enable_device(unsigned long attrib_phys)
static int smc_enable_device(struct platform_device *pdev)
{
unsigned long flags;
unsigned char ecor, ecsr;
void *addr;
void __iomem *addr;
struct resource * res;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
if (!res)
return 0;
/*
* Map the attribute space. This is overkill, but clean.
*/
addr = ioremap(attrib_phys, ATTRIB_SIZE);
addr = ioremap(res->start, ATTRIB_SIZE);
if (!addr)
return -ENOMEM;
......@@ -2069,6 +2099,62 @@ static int smc_enable_device(unsigned long attrib_phys)
return 0;
}
static int smc_request_attrib(struct platform_device *pdev)
{
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
if (!res)
return 0;
if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME))
return -EBUSY;
return 0;
}
static void smc_release_attrib(struct platform_device *pdev)
{
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
if (res)
release_mem_region(res->start, ATTRIB_SIZE);
}
#ifdef SMC_CAN_USE_DATACS
static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev)
{
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
struct smc_local *lp = netdev_priv(ndev);
if (!res)
return;
if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) {
printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME);
return;
}
lp->datacs = ioremap(res->start, SMC_DATA_EXTENT);
}
static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
{
struct smc_local *lp = netdev_priv(ndev);
struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
if (lp->datacs)
iounmap(lp->datacs);
lp->datacs = NULL;
if (res)
release_mem_region(res->start, SMC_DATA_EXTENT);
}
#else
static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) {}
static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) {}
#endif
/*
* smc_init(void)
* Input parameters:
......@@ -2084,20 +2170,20 @@ static int smc_drv_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev;
struct resource *res, *ext = NULL;
unsigned int *addr;
struct resource *res;
unsigned int __iomem *addr;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
if (!res)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
goto out;
}
/*
* Request the regions.
*/
if (!request_mem_region(res->start, SMC_IO_EXTENT, "smc91x")) {
if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
ret = -EBUSY;
goto out;
}
......@@ -2106,7 +2192,7 @@ static int smc_drv_probe(struct device *dev)
if (!ndev) {
printk("%s: could not allocate device.\n", CARDNAME);
ret = -ENOMEM;
goto release_1;
goto out_release_io;
}
SET_MODULE_OWNER(ndev);
SET_NETDEV_DEV(ndev, dev);
......@@ -2114,42 +2200,26 @@ static int smc_drv_probe(struct device *dev)
ndev->dma = (unsigned char)-1;
ndev->irq = platform_get_irq(pdev, 0);
ext = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (ext) {
if (!request_mem_region(ext->start, ATTRIB_SIZE, ndev->name)) {
ret = -EBUSY;
goto release_1;
}
ret = smc_request_attrib(pdev);
if (ret)
goto out_free_netdev;
#if defined(CONFIG_SA1100_ASSABET)
NCR_0 |= NCR_ENET_OSC_EN;
NCR_0 |= NCR_ENET_OSC_EN;
#endif
ret = smc_enable_device(ext->start);
if (ret)
goto release_both;
}
ret = smc_enable_device(pdev);
if (ret)
goto out_release_attrib;
addr = ioremap(res->start, SMC_IO_EXTENT);
if (!addr) {
ret = -ENOMEM;
goto release_both;
goto out_release_attrib;
}
dev_set_drvdata(dev, ndev);
ret = smc_probe(ndev, (unsigned long)addr);
if (ret != 0) {
dev_set_drvdata(dev, NULL);
iounmap(addr);
release_both:
if (ext)
release_mem_region(ext->start, ATTRIB_SIZE);
free_netdev(ndev);
release_1:
release_mem_region(res->start, SMC_IO_EXTENT);
out:
printk("%s: not found (%d).\n", CARDNAME, ret);
}
ret = smc_probe(ndev, addr);
if (ret != 0)
goto out_iounmap;
#ifdef SMC_USE_PXA_DMA
else {
struct smc_local *lp = netdev_priv(ndev);
......@@ -2157,6 +2227,22 @@ static int smc_drv_probe(struct device *dev)
}
#endif
smc_request_datacs(pdev, ndev);
return 0;
out_iounmap:
dev_set_drvdata(dev, NULL);
iounmap(addr);
out_release_attrib:
smc_release_attrib(pdev);
out_free_netdev:
free_netdev(ndev);
out_release_io:
release_mem_region(res->start, SMC_IO_EXTENT);
out:
printk("%s: not found (%d).\n", CARDNAME, ret);
return ret;
}
......@@ -2164,6 +2250,7 @@ static int smc_drv_remove(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = dev_get_drvdata(dev);
struct smc_local *lp = netdev_priv(ndev);
struct resource *res;
dev_set_drvdata(dev, NULL);
......@@ -2176,11 +2263,14 @@ static int smc_drv_remove(struct device *dev)
if (ndev->dma != (unsigned char)-1)
pxa_free_dma(ndev->dma);
#endif
iounmap((void *)ndev->base_addr);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res)
release_mem_region(res->start, ATTRIB_SIZE);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
iounmap(lp->base);
smc_release_datacs(pdev,ndev);
smc_release_attrib(pdev);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
if (!res)
platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, SMC_IO_EXTENT);
free_netdev(ndev);
......@@ -2196,6 +2286,7 @@ static int smc_drv_suspend(struct device *dev, u32 state, u32 level)
if (netif_running(ndev)) {
netif_device_detach(ndev);
smc_shutdown(ndev);
smc_phy_powerdown(ndev);
}
}
return 0;
......@@ -2208,9 +2299,7 @@ static int smc_drv_resume(struct device *dev, u32 level)
if (ndev && level == RESUME_ENABLE) {
struct smc_local *lp = netdev_priv(ndev);
if (pdev->num_resources == 3)
smc_enable_device(pdev->resource[2].start);
smc_enable_device(pdev);
if (netif_running(ndev)) {
smc_reset(ndev);
smc_enable(ndev);
......
......@@ -162,6 +162,26 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
}
}
#elif defined(CONFIG_ARCH_OMAP)
/* We can only do 16-bit reads and writes in the static memory space. */
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
#define SMC_inb(a, r) readb((a) + (r))
#define SMC_outb(v, a, r) writeb(v, (a) + (r))
#define SMC_inw(a, r) readw((a) + (r))
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
#define SMC_inl(a, r) readl((a) + (r))
#define SMC_outl(v, a, r) writel(v, (a) + (r))
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
#elif defined(CONFIG_ISA)
#define SMC_CAN_USE_8BIT 1
......@@ -362,7 +382,7 @@ smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs)
#define SMC_IO_SHIFT 0
#endif
#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT)
#define SMC_DATA_EXTENT (4)
/*
. Bank Select Register:
......@@ -883,7 +903,7 @@ static const char * chip_ids[ 16 ] = {
#endif
#if SMC_CAN_USE_32BIT
#define SMC_PUSH_DATA(p, l) \
#define _SMC_PUSH_DATA(p, l) \
do { \
char *__ptr = (p); \
int __len = (l); \
......@@ -898,7 +918,7 @@ static const char * chip_ids[ 16 ] = {
SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
} \
} while (0)
#define SMC_PULL_DATA(p, l) \
#define _SMC_PULL_DATA(p, l) \
do { \
char *__ptr = (p); \
int __len = (l); \
......@@ -918,11 +938,11 @@ static const char * chip_ids[ 16 ] = {
SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \
} while (0)
#elif SMC_CAN_USE_16BIT
#define SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
#define SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
#define _SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
#define _SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
#elif SMC_CAN_USE_8BIT
#define SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
#define SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
#define _SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
#define _SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
#endif
#if ! SMC_CAN_USE_16BIT
......@@ -941,6 +961,51 @@ static const char * chip_ids[ 16 ] = {
})
#endif
#if SMC_CAN_USE_DATACS
#define SMC_PUSH_DATA(p, l) \
if ( lp->datacs ) { \
unsigned char *__ptr = (p); \
int __len = (l); \
if (__len >= 2 && (unsigned long)__ptr & 2) { \
__len -= 2; \
SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
__ptr += 2; \
} \
outsl(lp->datacs, __ptr, __len >> 2); \
if (__len & 2) { \
__ptr += (__len & ~3); \
SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
} \
} else { \
_SMC_PUSH_DATA(p, l); \
}
#define SMC_PULL_DATA(p, l) \
if ( lp->datacs ) { \
unsigned char *__ptr = (p); \
int __len = (l); \
if ((unsigned long)__ptr & 2) { \
/* \
* We want 32bit alignment here. \
* Since some buses perform a full 32bit \
* fetch even for 16bit data we can't use \
* SMC_inw() here. Back both source (on chip \
* and destination) pointers of 2 bytes. \
*/ \
__ptr -= 2; \
__len += 2; \
SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \
} \
__len += 2; \
insl( lp->datacs, __ptr, __len >> 2); \
} else { \
_SMC_PULL_DATA(p, l); \
}
#else
#define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l)
#define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l)
#endif
#if !defined (SMC_INTERRUPT_PREAMBLE)
# define SMC_INTERRUPT_PREAMBLE
#endif
......
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