diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-04-21 18:34:12 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-04-21 18:34:12 -0700 |
| commit | df42471d85d64d8f54eeb842ad079cfba7564a11 (patch) | |
| tree | 2046ad2e0eed81640616151fc82163c5e71ae408 | |
| parent | cacf648951e1833a362c38fb45243e988cee8e0f (diff) | |
| parent | 2c8e5e76127d3fb3d6a435b234ed08836683f091 (diff) | |
Merge bk://kernel.bkbits.net/davem/sparc-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
| -rw-r--r-- | drivers/block/ll_rw_blk.c | 6 | ||||
| -rw-r--r-- | drivers/block/umem.c | 89 | ||||
| -rw-r--r-- | fs/jfs/jfs_txnmgr.c | 15 | ||||
| -rw-r--r-- | include/linux/umem.h | 7 |
4 files changed, 91 insertions, 26 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 74d8e2e0f8db..ad6e7b62e66f 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -2164,8 +2164,7 @@ int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes) void end_that_request_last(struct request *req) { struct gendisk *disk = req->rq_disk; - if (req->waiting) - complete(req->waiting); + struct completion *waiting = req->waiting; if (disk) { unsigned long duration = jiffies - req->start_time; @@ -2183,6 +2182,9 @@ void end_that_request_last(struct request *req) disk_stat_dec(disk, in_flight); } __blk_put_request(req->q, req); + /* Do this LAST! The structure may be freed immediately afterwards */ + if (waiting) + complete(waiting); } int __init blk_dev_init(void) diff --git a/drivers/block/umem.c b/drivers/block/umem.c index edb915b60ceb..ddfe3bb53b32 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -149,6 +149,7 @@ struct cardinfo { spinlock_t lock; int check_batteries; + int flags; }; static struct cardinfo cards[MM_MAXCARDS]; @@ -573,7 +574,7 @@ static int mm_make_request(request_queue_t *q, struct bio *bio) -- mm_interrupt ----------------------------------------------------------------------------------- */ -static void mm_interrupt(int irq, void *__card, struct pt_regs *regs) +static irqreturn_t mm_interrupt(int irq, void *__card, struct pt_regs *regs) { struct cardinfo *card = (struct cardinfo *) __card; unsigned int dma_status; @@ -585,13 +586,16 @@ HW_TRACE(0x30); if (!(dma_status & (DMASCR_ERROR_MASK | DMASCR_CHAIN_COMPLETE))) { /* interrupt wasn't for me ... */ - return; + return IRQ_NONE; } /* clear COMPLETION interrupts */ - writel(cpu_to_le32(DMASCR_DMA_COMPLETE|DMASCR_CHAIN_COMPLETE), - card->csr_remap+ DMA_STATUS_CTRL); - + if (card->flags & UM_FLAG_NO_BYTE_STATUS) + writel(cpu_to_le32(DMASCR_DMA_COMPLETE|DMASCR_CHAIN_COMPLETE), + card->csr_remap+ DMA_STATUS_CTRL); + else + writeb((DMASCR_DMA_COMPLETE|DMASCR_CHAIN_COMPLETE) >> 16, + card->csr_remap+ DMA_STATUS_CTRL + 2); /* log errors and clear interrupt status */ if (dma_status & DMASCR_ANY_ERR) { @@ -663,6 +667,7 @@ HW_TRACE(0x30); HW_TRACE(0x36); + return IRQ_HANDLED; } /* ----------------------------------------------------------------------------------- @@ -755,15 +760,16 @@ static void check_all_batteries(unsigned long ptr) { int i; - for (i = 0; i < num_cards; i++) { - struct cardinfo *card = &cards[i]; - spin_lock_bh(&card->lock); - if (card->Active >= 0) - card->check_batteries = 1; - else - check_batteries(card); - spin_unlock_bh(&card->lock); - } + for (i = 0; i < num_cards; i++) + if (!(cards[i].flags & UM_FLAG_NO_BATT)) { + struct cardinfo *card = &cards[i]; + spin_lock_bh(&card->lock); + if (card->Active >= 0) + card->check_batteries = 1; + else + check_batteries(card); + spin_unlock_bh(&card->lock); + } init_battery_timer(); } @@ -869,6 +875,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i unsigned char mem_present; unsigned char batt_status; unsigned int saved_bar, data; + int magic_number; if (pci_enable_device(dev) < 0) return -ENODEV; @@ -933,12 +940,33 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i printk(KERN_INFO "MM%d: MEM area not remapped (CONFIG_MM_MAP_MEMORY not set)\n", card->card_number); #endif - if (readb(card->csr_remap + MEMCTRLSTATUS_MAGIC) != MM_MAGIC_VALUE) { + switch(card->dev->device) { + case 0x5415: + card->flags |= UM_FLAG_NO_BYTE_STATUS | UM_FLAG_NO_BATTREG; + magic_number = 0x59; + break; + + case 0x5425: + card->flags |= UM_FLAG_NO_BYTE_STATUS; + magic_number = 0x5C; + break; + + case 0x6155: + card->flags |= UM_FLAG_NO_BYTE_STATUS | UM_FLAG_NO_BATTREG | UM_FLAG_NO_BATT; + magic_number = 0x99; + break; + + default: + magic_number = 0x100; + break; + } + + if (readb(card->csr_remap + MEMCTRLSTATUS_MAGIC) != magic_number) { printk(KERN_ERR "MM%d: Magic number invalid\n", card->card_number); ret = -ENOMEM; - goto failed_magic; } + card->mm_pages[0].desc = pci_alloc_consistent(card->dev, PAGE_SIZE*2, &card->mm_pages[0].page_dma); @@ -997,14 +1025,19 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i card->battery[1].good = !(batt_status & BATTERY_2_FAILURE); card->battery[0].last_change = card->battery[1].last_change = jiffies; - printk(KERN_INFO "MM%d: Size %d KB, Battery 1 %s (%s), Battery 2 %s (%s)\n", - card->card_number, card->mm_size, - (batt_status & BATTERY_1_DISABLED ? "Disabled" : "Enabled"), - card->battery[0].good ? "OK" : "FAILURE", - (batt_status & BATTERY_2_DISABLED ? "Disabled" : "Enabled"), - card->battery[1].good ? "OK" : "FAILURE"); + if (card->flags & UM_FLAG_NO_BATT) + printk(KERN_INFO "MM%d: Size %d KB\n", + card->card_number, card->mm_size); + else { + printk(KERN_INFO "MM%d: Size %d KB, Battery 1 %s (%s), Battery 2 %s (%s)\n", + card->card_number, card->mm_size, + (batt_status & BATTERY_1_DISABLED ? "Disabled" : "Enabled"), + card->battery[0].good ? "OK" : "FAILURE", + (batt_status & BATTERY_2_DISABLED ? "Disabled" : "Enabled"), + card->battery[1].good ? "OK" : "FAILURE"); - set_fault_to_battery_status(card); + set_fault_to_battery_status(card); + } pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &saved_bar); data = 0xffffffff; @@ -1117,6 +1150,16 @@ static const struct pci_device_id __devinitdata mm_pci_ids[] = { { }, { .vendor = PCI_VENDOR_ID_MICRO_MEMORY, .device = PCI_DEVICE_ID_MICRO_MEMORY_5425CN, + }, { + .vendor = PCI_VENDOR_ID_MICRO_MEMORY, + .device = PCI_DEVICE_ID_MICRO_MEMORY_6155, + }, { + .vendor = 0x8086, + .device = 0xB555, + .subvendor= 0x1332, + .subdevice= 0x5460, + .class = 0x050000, + .class_mask= 0, }, { /* end: all zeroes */ } }; diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 5d013b2d6d25..d7740cc3fb37 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -1240,8 +1240,21 @@ int txCommit(tid_t tid, /* transaction identifier */ * Ensure that inode isn't reused before * lazy commit thread finishes processing */ - if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE)) + if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE)) { atomic_inc(&tblk->ip->i_count); + /* + * Avoid a rare deadlock + * + * If the inode is locked, we may be blocked in + * jfs_commit_inode. If so, we don't want the + * lazy_commit thread doing the last iput() on the inode + * since that may block on the locked inode. Instead, + * commit the transaction synchronously, so the last iput + * will be done by the calling thread (or later) + */ + if (tblk->ip->i_state & I_LOCK) + tblk->xflag &= ~COMMIT_LAZY; + } ASSERT((!(tblk->xflag & COMMIT_DELETE)) || ((tblk->ip->i_nlink == 0) && diff --git a/include/linux/umem.h b/include/linux/umem.h index d6e89299de31..2eb1f55644cc 100644 --- a/include/linux/umem.h +++ b/include/linux/umem.h @@ -128,4 +128,11 @@ struct mm_dma_desc { #define PCI_VENDOR_ID_MICRO_MEMORY 0x1332 #define PCI_DEVICE_ID_MICRO_MEMORY_5415CN 0x5415 #define PCI_DEVICE_ID_MICRO_MEMORY_5425CN 0x5425 +#define PCI_DEVICE_ID_MICRO_MEMORY_6155 0x6155 + +/* bits for card->flags */ +#define UM_FLAG_DMA_IN_REGS 1 +#define UM_FLAG_NO_BYTE_STATUS 2 +#define UM_FLAG_NO_BATTREG 4 +#define UM_FLAG_NO_BATT 8 #endif |
