--- /home/mike/kernel/patches/tifm/upstream/linux/tifm.h 2007-02-17 08:59:38.000000000 -0500 +++ /home/mike/kernel/patches/work/linux-2.6.21-gentoo/include/linux/tifm.h 2007-05-01 14:21:11.000000000 -0400 @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -23,7 +22,8 @@ enum { FM_SET_INTERRUPT_ENABLE = 0x008, FM_CLEAR_INTERRUPT_ENABLE = 0x00c, - FM_INTERRUPT_STATUS = 0x014 }; + FM_INTERRUPT_STATUS = 0x014 +}; /* Socket registers (relative to socket base address): */ enum { @@ -67,15 +67,15 @@ enum { #define TIFM_SOCK_STATE_OCCUPIED 0x00000008 #define TIFM_SOCK_STATE_POWERED 0x00000080 -#define TIFM_FIFO_ENABLE 0x00000001 /* Meaning of this constant is unverified */ -#define TIFM_FIFO_READY 0x00000001 /* Meaning of this constant is unverified */ +#define TIFM_FIFO_ENABLE 0x00000001 +#define TIFM_FIFO_READY 0x00000001 #define TIFM_FIFO_INT_SETALL 0x0000ffff -#define TIFM_FIFO_INTMASK 0x00000005 /* Meaning of this constant is unverified */ +#define TIFM_FIFO_INTMASK 0x00000005 -#define TIFM_DMA_RESET 0x00000002 /* Meaning of this constant is unverified */ -#define TIFM_DMA_TX 0x00008000 /* Meaning of this constant is unverified */ -#define TIFM_DMA_EN 0x00000001 /* Meaning of this constant is unverified */ -#define TIFM_DMA_TSIZE 0x0000007f /* Meaning of this constant is unverified */ +#define TIFM_DMA_RESET 0x00000002 +#define TIFM_DMA_TX 0x00008000 +#define TIFM_DMA_EN 0x00000001 +#define TIFM_DMA_TSIZE 0x0000007f #define TIFM_TYPE_XD 1 #define TIFM_TYPE_MS 2 @@ -92,7 +92,7 @@ struct tifm_dev { unsigned char type; unsigned int socket_id; - void (*event)(struct tifm_dev *sock); + void (*card_event)(struct tifm_dev *sock); void (*data_event)(struct tifm_dev *sock); struct device dev; @@ -106,34 +106,25 @@ struct tifm_driver { pm_message_t state); int (*resume)(struct tifm_dev *dev); - struct device_driver driver; -}; - -/* Socket caps: */ -enum { - TIFM_SOCK_XD_CAP = 0x0001, // socket supports xD cards - TIFM_SOCK_MS_PIF = 0x0002 // socket has Memorystick parallel i/f + struct device_driver driver; }; struct tifm_adapter { - char __iomem *addr; - spinlock_t lock; - unsigned int irq_status; - unsigned int socket_change_set; - unsigned int id; - unsigned int num_sockets; - struct completion *finish_me; - - struct work_struct media_switcher; - struct class_device cdev; - - void (*eject)(struct tifm_adapter *fm, - struct tifm_dev *sock); - - struct socket_t { - struct tifm_dev *dev; - unsigned int caps; - } sockets[0]; + char __iomem *addr; + spinlock_t lock; + unsigned int irq_status; + unsigned int socket_change_set; + unsigned int id; + unsigned int num_sockets; + struct completion *finish_me; + + struct work_struct media_switcher; + struct class_device cdev; + + void (*eject)(struct tifm_adapter *fm, + struct tifm_dev *sock); + + struct tifm_dev *sockets[0]; }; struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, @@ -149,7 +140,6 @@ struct tifm_dev *tifm_alloc_device(struc int tifm_register_driver(struct tifm_driver *drv); void tifm_unregister_driver(struct tifm_driver *drv); void tifm_eject(struct tifm_dev *sock); -unsigned int tifm_get_sock_caps(struct tifm_dev *sock); int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, int direction); void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, @@ -158,7 +148,7 @@ void tifm_queue_work(struct work_struct static inline void *tifm_get_drvdata(struct tifm_dev *dev) { - return dev_get_drvdata(&dev->dev); + return dev_get_drvdata(&dev->dev); } static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data) --- /home/mike/kernel/patches/tifm/upstream/tifm_7xx1.c 2007-02-25 02:26:29.000000000 -0500 +++ /home/mike/kernel/patches/work/linux-2.6.21-gentoo/drivers/misc/tifm_7xx1.c 2007-05-01 14:21:11.000000000 -0400 @@ -9,8 +9,7 @@ * */ -#include "linux/tifm.h" -#include "linux/pci_ids.h" +#include #define DRIVER_NAME "tifm_7xx1" #define DRIVER_VERSION "0.8" @@ -53,12 +52,12 @@ static irqreturn_t tifm_7xx1_isr(int irq writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); for (cnt = 0; cnt < fm->num_sockets; cnt++) { - sock = fm->sockets[cnt].dev; + sock = fm->sockets[cnt]; if (sock) { if ((irq_status >> cnt) & TIFM_IRQ_FIFOMASK(1)) sock->data_event(sock); if ((irq_status >> cnt) & TIFM_IRQ_CARDMASK(1)) - sock->event(sock); + sock->card_event(sock); } } @@ -78,15 +77,13 @@ static irqreturn_t tifm_7xx1_isr(int irq return IRQ_HANDLED; } -static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, - unsigned int caps) +static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr) { unsigned int s_state; int cnt; writel(0x0e00, sock_addr + SOCK_CONTROL); - /* half a second should be enough */ for (cnt = 16; cnt <= 256; cnt <<= 1) { if (!(TIFM_SOCK_STATE_POWERED & readl(sock_addr + SOCK_PRESENT_STATE))) @@ -102,13 +99,14 @@ static unsigned char tifm_7xx1_toggle_so writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED, sock_addr + SOCK_CONTROL); - if (caps & TIFM_SOCK_XD_CAP) { - if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) == 1) - msleep(40); - } - writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL); - msleep(10); + /* xd needs some extra time before power on */ + if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) + == TIFM_TYPE_XD) + msleep(40); + writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL); + /* wait for power to stabilize */ + msleep(20); for (cnt = 16; cnt <= 256; cnt <<= 1) { if ((TIFM_SOCK_STATE_POWERED & readl(sock_addr + SOCK_PRESENT_STATE))) @@ -153,12 +151,12 @@ static void tifm_7xx1_switch_media(struc for (cnt = 0; cnt < fm->num_sockets; cnt++) { if (!(socket_change_set & (1 << cnt))) continue; - sock = fm->sockets[cnt].dev; + sock = fm->sockets[cnt]; if (sock) { printk(KERN_INFO "%s : demand removing card from socket %u:%u\n", fm->cdev.class_id, fm->id, cnt); - fm->sockets[cnt].dev = NULL; + fm->sockets[cnt] = NULL; spin_unlock_irqrestore(&fm->lock, flags); device_unregister(&sock->dev); spin_lock_irqsave(&fm->lock, flags); @@ -169,8 +167,7 @@ static void tifm_7xx1_switch_media(struc spin_unlock_irqrestore(&fm->lock, flags); media_id = tifm_7xx1_toggle_sock_power( - tifm_7xx1_sock_addr(fm->addr, cnt), - fm->sockets[cnt].caps); + tifm_7xx1_sock_addr(fm->addr, cnt)); // tifm_alloc_device will check if media_id is valid sock = tifm_alloc_device(fm, cnt, media_id); @@ -179,8 +176,8 @@ static void tifm_7xx1_switch_media(struc if (!device_register(&sock->dev)) { spin_lock_irqsave(&fm->lock, flags); - if (!fm->sockets[cnt].dev) { - fm->sockets[cnt].dev = sock; + if (!fm->sockets[cnt]) { + fm->sockets[cnt] = sock; sock = NULL; } spin_unlock_irqrestore(&fm->lock, flags); @@ -236,12 +233,11 @@ static int tifm_7xx1_resume(struct pci_d for (rc = 0; rc < fm->num_sockets; rc++) new_ids[rc] = tifm_7xx1_toggle_sock_power( - tifm_7xx1_sock_addr(fm->addr, rc), - fm->sockets[rc].caps); + tifm_7xx1_sock_addr(fm->addr, rc)); spin_lock_irqsave(&fm->lock, flags); for (rc = 0; rc < fm->num_sockets; rc++) { - if (fm->sockets[rc].dev) { - if (fm->sockets[rc].dev->type == new_ids[rc]) + if (fm->sockets[rc]) { + if (fm->sockets[rc]->type == new_ids[rc]) good_sockets |= 1 << rc; else bad_sockets |= 1 << rc; @@ -271,7 +267,7 @@ static int tifm_7xx1_resume(struct pci_d } fm->socket_change_set |= bad_sockets; - if (fm->socket_change_set) + if (fm->socket_change_set) tifm_queue_work(&fm->media_switcher); spin_unlock_irqrestore(&fm->lock, flags); @@ -320,18 +316,6 @@ static int tifm_7xx1_probe(struct pci_de goto err_out_int; } - switch (fm->num_sockets) { - case 2: - fm->sockets[0].caps |= TIFM_SOCK_MS_PIF; - break; - case 4: - fm->sockets[0].caps |= TIFM_SOCK_XD_CAP; - fm->sockets[1].caps |= TIFM_SOCK_XD_CAP; - fm->sockets[2].caps |= TIFM_SOCK_XD_CAP | TIFM_SOCK_MS_PIF; - fm->sockets[3].caps |= TIFM_SOCK_XD_CAP; - break; - } - INIT_WORK(&fm->media_switcher, tifm_7xx1_switch_media); fm->eject = tifm_7xx1_eject; pci_set_drvdata(dev, fm); --- /home/mike/kernel/patches/tifm/upstream/tifm_core.c 2007-02-17 02:37:01.000000000 -0500 +++ /home/mike/kernel/patches/work/linux-2.6.21-gentoo/drivers/misc/tifm_core.c 2007-05-01 14:21:11.000000000 -0400 @@ -9,7 +9,7 @@ * */ -#include "linux/tifm.h" +#include #include #include @@ -101,7 +101,7 @@ static int tifm_device_remove(struct dev driver); if (dev->driver && drv->remove) { - sock->event = tifm_dummy_event; + sock->card_event = tifm_dummy_event; sock->data_event = tifm_dummy_event; drv->remove(sock); sock->dev.driver = NULL; @@ -155,14 +155,14 @@ static struct device_attribute tifm_dev_ }; static struct bus_type tifm_bus_type = { - .name = "tifm", - .dev_attrs = tifm_dev_attrs, - .match = tifm_bus_match, - .uevent = tifm_uevent, - .probe = tifm_device_probe, - .remove = tifm_device_remove, - .suspend = tifm_device_suspend, - .resume = tifm_device_resume + .name = "tifm", + .dev_attrs = tifm_dev_attrs, + .match = tifm_bus_match, + .uevent = tifm_uevent, + .probe = tifm_device_probe, + .remove = tifm_device_remove, + .suspend = tifm_device_suspend, + .resume = tifm_device_resume }; static void tifm_free(struct class_device *cdev) @@ -183,7 +183,7 @@ struct tifm_adapter *tifm_alloc_adapter( struct tifm_adapter *fm; fm = kzalloc(sizeof(struct tifm_adapter) - + sizeof(struct socket_t) * num_sockets, GFP_KERNEL); + + sizeof(struct tifm_dev*) * num_sockets, GFP_KERNEL); if (fm) { fm->cdev.class = &tifm_adapter_class; fm->cdev.dev = dev; @@ -214,10 +214,9 @@ int tifm_add_adapter(struct tifm_adapter spin_lock(&tifm_adapter_lock); idr_remove(&tifm_adapter_idr, fm->id); spin_unlock(&tifm_adapter_lock); - return rc; } - return 0; + return rc; } EXPORT_SYMBOL(tifm_add_adapter); @@ -227,8 +226,8 @@ void tifm_remove_adapter(struct tifm_ada flush_workqueue(workqueue); for (cnt = 0; cnt < fm->num_sockets; ++cnt) { - if (fm->sockets[cnt].dev) - device_unregister(&fm->sockets[cnt].dev->dev); + if (fm->sockets[cnt]) + device_unregister(&fm->sockets[cnt]->dev); } spin_lock(&tifm_adapter_lock); @@ -264,7 +263,7 @@ struct tifm_dev *tifm_alloc_device(struc spin_lock_init(&sock->lock); sock->type = type; sock->socket_id = id; - sock->event = tifm_dummy_event; + sock->card_event = tifm_dummy_event; sock->data_event = tifm_dummy_event; sock->dev.parent = fm->cdev.dev; --- /home/mike/kernel/patches/tifm/upstream/tifm_sd.c 2007-03-13 09:09:55.000000000 -0400 +++ /home/mike/kernel/patches/work/linux-2.6.21-gentoo/drivers/mmc/tifm_sd.c 2007-05-01 14:21:11.000000000 -0400 @@ -12,10 +12,11 @@ */ -#include "linux/tifm.h" +#include #include #include #include +#include #include #define DRIVER_NAME "tifm_sd" @@ -74,7 +75,7 @@ module_param(fixed_timeout, bool, 0644); #define TIFM_MMCSD_CMD_AC 0x2000 #define TIFM_MMCSD_CMD_ADTC 0x3000 -#define TIFM_MMCSD_MAX_BLOCK_SIZE 0x0800 +#define TIFM_MMCSD_MAX_BLOCK_SIZE 0x0800UL enum { CMD_READY = 0x0001, @@ -279,15 +280,13 @@ int tifm_sd_set_dma_data(struct tifm_sd return 1; } - while (1) { - dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - - host->block_pos; - if (dma_len) - break; + dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - host->block_pos; + if (!dma_len) { host->block_pos = 0; host->sg_pos++; if (host->sg_pos == host->sg_len) return 1; + dma_len = sg_dma_len(&r_data->sg[host->sg_pos]); } if (dma_len < t_size) { @@ -373,8 +372,10 @@ static unsigned int tifm_sd_op_flags(str static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) { struct tifm_dev *sock = host->dev; - unsigned int cmd_mask = tifm_sd_op_flags(cmd) | - (host->open_drain ? TIFM_MMCSD_ODTO : 0); + unsigned int cmd_mask = tifm_sd_op_flags(cmd); + + if (host->open_drain) + cmd_mask |= TIFM_MMCSD_ODTO; if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) cmd_mask |= TIFM_MMCSD_READ; @@ -500,7 +501,7 @@ static void tifm_sd_data_event(struct ti } /* Called from interrupt handler */ -static void tifm_sd_event(struct tifm_dev *sock) +static void tifm_sd_card_event(struct tifm_dev *sock) { struct tifm_sd *host; unsigned int host_status = 0; @@ -659,9 +660,8 @@ static void tifm_sd_request(struct mmc_h host->sg_len = r_data->sg_len; } else { - host->bounce_buf.offset - = offset_in_page(host->bounce_buf_data); - host->bounce_buf.length = r_data->blksz; + sg_init_one(&host->bounce_buf, host->bounce_buf_data, + r_data->blksz); if(1 != tifm_map_sg(sock, &host->bounce_buf, 1, r_data->flags & MMC_DATA_WRITE @@ -964,8 +964,6 @@ static int tifm_sd_probe(struct tifm_dev host->dev = sock; host->timeout_jiffies = msecs_to_jiffies(1000); - host->bounce_buf.page = virt_to_page(host->bounce_buf_data); - tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd, (unsigned long)host); setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); @@ -976,19 +974,14 @@ static int tifm_sd_probe(struct tifm_dev mmc->f_min = 20000000 / 60; mmc->f_max = 24000000; -// mmc->max_blk_count = 2048; -// mmc->max_hw_segs = mmc->max_blk_count; - mmc->max_hw_segs = 16; -// mmc->max_blk_size = min(2048, PAGE_SIZE); -// mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size; - mmc->max_seg_size = 127 * 2048; - + mmc->max_blk_count = 2048; + mmc->max_hw_segs = mmc->max_blk_count; + mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE); + mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size; + mmc->max_req_size = mmc->max_seg_size; mmc->max_phys_segs = mmc->max_hw_segs; - mmc->max_sectors = 127 * mmc->max_phys_segs; - -// mmc->max_req_size = mmc->max_seg_size; - sock->event = tifm_sd_event; + sock->card_event = tifm_sd_card_event; sock->data_event = tifm_sd_data_event; rc = tifm_sd_initialize_host(host); @@ -1007,12 +1000,15 @@ static void tifm_sd_remove(struct tifm_d struct tifm_sd *host = mmc_priv(mmc); unsigned long flags; - tasklet_kill(&host->finish_tasklet); spin_lock_irqsave(&sock->lock, flags); host->eject = 1; writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); mmiowb(); + spin_unlock_irqrestore(&sock->lock, flags); + tasklet_kill(&host->finish_tasklet); + + spin_lock_irqsave(&sock->lock, flags); if (host->req) { writel(TIFM_FIFO_INT_SETALL, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); @@ -1023,8 +1019,6 @@ static void tifm_sd_remove(struct tifm_d tasklet_schedule(&host->finish_tasklet); } spin_unlock_irqrestore(&sock->lock, flags); - // temporary hack - msleep(1000); mmc_remove_host(mmc); dev_dbg(&sock->dev, "after remove\n");