Commit b83290ea authored by Dave Jones's avatar Dave Jones

Merge delerium.codemonkey.org.uk:/mnt/nfs/sepia/bar/src/kernel/2.6/trees/bk-linus

into delerium.codemonkey.org.uk:/mnt/nfs/sepia/bar/src/kernel/2.6/trees/agpgart
parents 06477bc3 e689bf58
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -test10 EXTRAVERSION = -test11
# *DOCUMENTATION* # *DOCUMENTATION*
# To see a list of typical targets execute "make help" # To see a list of typical targets execute "make help"
......
...@@ -1910,7 +1910,7 @@ unw_unwind_to_user (struct unw_frame_info *info) ...@@ -1910,7 +1910,7 @@ unw_unwind_to_user (struct unw_frame_info *info)
__FUNCTION__, ip); __FUNCTION__, ip);
return -1; return -1;
} }
if (ip < GATE_ADDR) if (ip < FIXADDR_USER_END)
return 0; return 0;
} }
unw_get_ip(info, &ip); unw_get_ip(info, &ip);
......
...@@ -472,6 +472,15 @@ extern __inline__ unsigned long do_gettimeoffset(void) ...@@ -472,6 +472,15 @@ extern __inline__ unsigned long do_gettimeoffset(void)
return (*master_l10_counter >> 10) & 0x1fffff; return (*master_l10_counter >> 10) & 0x1fffff;
} }
/*
* Returns nanoseconds
* XXX This is a suboptimal implementation.
*/
unsigned long long sched_clock(void)
{
return (unsigned long long)jiffies * (1000000000 / HZ);
}
/* Ok, my cute asm atomicity trick doesn't work anymore. /* Ok, my cute asm atomicity trick doesn't work anymore.
* There are just too many variables that need to be protected * There are just too many variables that need to be protected
* now (both members of xtime, wall_jiffies, et al.) * now (both members of xtime, wall_jiffies, et al.)
......
...@@ -202,6 +202,7 @@ static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer, ...@@ -202,6 +202,7 @@ static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
if (csraddr < CSR_TOPOLOGY_MAP) { if (csraddr < CSR_TOPOLOGY_MAP) {
if (csraddr + length > CSR_CONFIG_ROM + host->csr.rom_size) { if (csraddr + length > CSR_CONFIG_ROM + host->csr.rom_size) {
spin_unlock_irqrestore(&host->csr.lock, flags);
return RCODE_ADDRESS_ERROR; return RCODE_ADDRESS_ERROR;
} }
src = ((char *)host->csr.rom) + csraddr - CSR_CONFIG_ROM; src = ((char *)host->csr.rom) + csraddr - CSR_CONFIG_ROM;
......
...@@ -98,7 +98,7 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, ...@@ -98,7 +98,7 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
return NULL; return NULL;
} }
hi = kmalloc(sizeof(*hi) + data_size, GFP_KERNEL); hi = kmalloc(sizeof(*hi) + data_size, GFP_ATOMIC);
if (!hi) if (!hi)
return NULL; return NULL;
......
...@@ -92,7 +92,7 @@ void hpsb_unref_host(struct hpsb_host *host) ...@@ -92,7 +92,7 @@ void hpsb_unref_host(struct hpsb_host *host)
down(&hpsb_hosts_lock); down(&hpsb_hosts_lock);
if (atomic_dec_and_test(&host->refcount) && host->is_shutdown) if (atomic_dec_and_test(&host->refcount) && host->is_shutdown)
kfree(host); device_unregister(&host->device);
up(&hpsb_hosts_lock); up(&hpsb_hosts_lock);
} }
......
...@@ -137,7 +137,7 @@ int hpsb_get_tlabel(struct hpsb_packet *packet) ...@@ -137,7 +137,7 @@ int hpsb_get_tlabel(struct hpsb_packet *packet)
tp = &packet->host->tpool[packet->node_id & NODE_MASK]; tp = &packet->host->tpool[packet->node_id & NODE_MASK];
if (in_interrupt() || in_atomic()) { if (irqs_disabled() || in_atomic()) {
if (down_trylock(&tp->count)) if (down_trylock(&tp->count))
return 1; return 1;
} else { } else {
......
...@@ -13,9 +13,6 @@ ...@@ -13,9 +13,6 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
/* The great kdev_t changeover in 2.5.x */
#include <linux/kdev_t.h>
/* Transaction Label handling */ /* Transaction Label handling */
struct hpsb_tlabel_pool { struct hpsb_tlabel_pool {
DECLARE_BITMAP(pool, 64); DECLARE_BITMAP(pool, 64);
......
This diff is collapsed.
...@@ -130,6 +130,7 @@ struct node_entry { ...@@ -130,6 +130,7 @@ struct node_entry {
struct hpsb_host *host; /* Host this node is attached to */ struct hpsb_host *host; /* Host this node is attached to */
nodeid_t nodeid; /* NodeID */ nodeid_t nodeid; /* NodeID */
struct bus_options busopt; /* Bus Options */ struct bus_options busopt; /* Bus Options */
int needs_probe;
unsigned int generation; /* Synced with hpsb generation */ unsigned int generation; /* Synced with hpsb generation */
/* The following is read from the config rom */ /* The following is read from the config rom */
......
...@@ -524,7 +524,7 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) ...@@ -524,7 +524,7 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base)
return 0; return 0;
out3: out3:
release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT); release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT);
out2: out2:
release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT); release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT);
out1: out1:
......
...@@ -352,7 +352,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) ...@@ -352,7 +352,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
if (!__pppoe_xmit( relay_po->sk, skb)) if (!__pppoe_xmit( relay_po->sk, skb))
goto abort_put; goto abort_put;
} else { } else {
sock_queue_rcv_skb(sk, skb); if (sock_queue_rcv_skb(sk, skb))
goto abort_kfree;
} }
return NET_RX_SUCCESS; return NET_RX_SUCCESS;
......
...@@ -133,7 +133,11 @@ void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf) ...@@ -133,7 +133,11 @@ void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
struct ata_ioports *ioaddr = &ap->ioaddr; struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
outb(tf->ctl, ioaddr->ctl_addr); if (tf->ctl != ap->last_ctl) {
outb(tf->ctl, ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
outb(tf->hob_feature, ioaddr->error_addr); outb(tf->hob_feature, ioaddr->error_addr);
...@@ -187,7 +191,11 @@ void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) ...@@ -187,7 +191,11 @@ void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
struct ata_ioports *ioaddr = &ap->ioaddr; struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
writeb(tf->ctl, ap->ioaddr.ctl_addr); if (tf->ctl != ap->last_ctl) {
writeb(tf->ctl, ap->ioaddr.ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
writeb(tf->hob_feature, (void *) ioaddr->error_addr); writeb(tf->hob_feature, (void *) ioaddr->error_addr);
...@@ -1281,9 +1289,9 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, ...@@ -1281,9 +1289,9 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
/* software reset. causes dev0 to be selected */ /* software reset. causes dev0 to be selected */
if (ap->flags & ATA_FLAG_MMIO) { if (ap->flags & ATA_FLAG_MMIO) {
writeb(ap->ctl, ioaddr->ctl_addr); writeb(ap->ctl, ioaddr->ctl_addr);
udelay(10); /* FIXME: flush */ udelay(20); /* FIXME: flush */
writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr); writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
udelay(10); /* FIXME: flush */ udelay(20); /* FIXME: flush */
writeb(ap->ctl, ioaddr->ctl_addr); writeb(ap->ctl, ioaddr->ctl_addr);
} else { } else {
outb(ap->ctl, ioaddr->ctl_addr); outb(ap->ctl, ioaddr->ctl_addr);
...@@ -2755,6 +2763,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, ...@@ -2755,6 +2763,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
ap->cbl = ATA_CBL_NONE; ap->cbl = ATA_CBL_NONE;
ap->device[0].flags = ATA_DFLAG_MASTER; ap->device[0].flags = ATA_DFLAG_MASTER;
ap->active_tag = ATA_TAG_POISON; ap->active_tag = ATA_TAG_POISON;
ap->last_ctl = 0xFF;
/* ata_engine init */ /* ata_engine init */
ap->eng.flags = 0; ap->eng.flags = 0;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define __LIBATA_H__ #define __LIBATA_H__
#define DRV_NAME "libata" #define DRV_NAME "libata"
#define DRV_VERSION "0.80" /* must be exactly four chars */ #define DRV_VERSION "0.81" /* must be exactly four chars */
struct ata_scsi_args { struct ata_scsi_args {
struct ata_port *ap; struct ata_port *ap;
......
...@@ -213,6 +213,8 @@ static struct pci_device_id pdc_sata_pci_tbl[] = { ...@@ -213,6 +213,8 @@ static struct pci_device_id pdc_sata_pci_tbl[] = {
board_2037x }, board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0, { PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x }, board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20319 }, board_20319 },
{ PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#endif /* CONFIG_ALL_PPC */ #endif /* CONFIG_ALL_PPC */
#define DRV_NAME "ata_k2" #define DRV_NAME "ata_k2"
#define DRV_VERSION "1.02" #define DRV_VERSION "1.03"
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
...@@ -69,8 +69,11 @@ static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) ...@@ -69,8 +69,11 @@ static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
struct ata_ioports *ioaddr = &ap->ioaddr; struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
writeb(tf->ctl, ioaddr->ctl_addr); if (tf->ctl != ap->last_ctl) {
writeb(tf->ctl, ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->error_addr); writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->error_addr);
writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr); writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
...@@ -311,13 +314,24 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e ...@@ -311,13 +314,24 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
rc = -ENODEV; rc = -ENODEV;
goto err_out_unmap; goto err_out_unmap;
} }
/* Clear a magic bit in SCR1 according to Darwin, those help
* some funky seagate drives (though so far, those were already
* set by the firmware on the machines I had access to
*/
writel(readl(mmio_base + 0x80) & ~0x00040000, mmio_base + 0x80);
/* Clear SATA error & interrupts we don't use */
writel(0xffffffff, mmio_base + 0x44);
writel(0x0, mmio_base + 0x88);
probe_ent->sht = &k2_sata_sht; probe_ent->sht = &k2_sata_sht;
probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
ATA_FLAG_SRST | ATA_FLAG_MMIO; ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO;
probe_ent->port_ops = &k2_sata_ops; probe_ent->port_ops = &k2_sata_ops;
probe_ent->n_ports = 2; probe_ent->n_ports = 2;
probe_ent->irq = pdev->irq; probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ; probe_ent->irq_flags = SA_SHIRQ;
probe_ent->mmio_base = mmio_base; probe_ent->mmio_base = mmio_base;
/* /*
......
...@@ -367,6 +367,16 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) ...@@ -367,6 +367,16 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
unsigned long timeout; unsigned long timeout;
int rtn = 0; int rtn = 0;
/* check if the device is still usable */
if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
/* in SDEV_DEL we error all commands. DID_NO_CONNECT
* returns an immediate error upwards, and signals
* that the device is no longer present */
cmd->result = DID_NO_CONNECT << 16;
scsi_done(cmd);
/* return 0 (because the command has been processed) */
goto out;
}
/* Assign a unique nonzero serial_number. */ /* Assign a unique nonzero serial_number. */
/* XXX(hch): this is racy */ /* XXX(hch): this is racy */
if (++serial_number == 0) if (++serial_number == 0)
...@@ -893,7 +903,7 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth) ...@@ -893,7 +903,7 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
*/ */
int scsi_device_get(struct scsi_device *sdev) int scsi_device_get(struct scsi_device *sdev)
{ {
if (test_bit(SDEV_DEL, &sdev->sdev_state)) if (sdev->sdev_state == SDEV_DEL)
return -ENXIO; return -ENXIO;
if (!get_device(&sdev->sdev_gendev)) if (!get_device(&sdev->sdev_gendev))
return -ENXIO; return -ENXIO;
...@@ -1015,7 +1025,7 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery) ...@@ -1015,7 +1025,7 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
struct list_head *lh, *lh_sf; struct list_head *lh, *lh_sf;
unsigned long flags; unsigned long flags;
set_bit(SDEV_CANCEL, &sdev->sdev_state); sdev->sdev_state = SDEV_CANCEL;
spin_lock_irqsave(&sdev->list_lock, flags); spin_lock_irqsave(&sdev->list_lock, flags);
list_for_each_entry(scmd, &sdev->cmd_list, list) { list_for_each_entry(scmd, &sdev->cmd_list, list) {
......
...@@ -911,7 +911,9 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) ...@@ -911,7 +911,9 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
if (rtn == SUCCESS) { if (rtn == SUCCESS) {
scsi_sleep(BUS_RESET_SETTLE_TIME); scsi_sleep(BUS_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host, scmd->device->channel); scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
} }
return rtn; return rtn;
...@@ -940,7 +942,9 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd) ...@@ -940,7 +942,9 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
if (rtn == SUCCESS) { if (rtn == SUCCESS) {
scsi_sleep(HOST_RESET_SETTLE_TIME); scsi_sleep(HOST_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host, scmd->device->channel); scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
} }
return rtn; return rtn;
...@@ -1608,7 +1612,7 @@ int scsi_error_handler(void *data) ...@@ -1608,7 +1612,7 @@ int scsi_error_handler(void *data)
* *
* Returns: Nothing * Returns: Nothing
* *
* Lock status: No locks are assumed held. * Lock status: Host lock must be held.
* *
* Notes: This only needs to be called if the reset is one which * Notes: This only needs to be called if the reset is one which
* originates from an unknown location. Resets originated * originates from an unknown location. Resets originated
...@@ -1622,7 +1626,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) ...@@ -1622,7 +1626,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
shost_for_each_device(sdev, shost) { __shost_for_each_device(sdev, shost) {
if (channel == sdev->channel) { if (channel == sdev->channel) {
sdev->was_reset = 1; sdev->was_reset = 1;
sdev->expecting_cc_ua = 1; sdev->expecting_cc_ua = 1;
...@@ -1642,7 +1646,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) ...@@ -1642,7 +1646,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
* *
* Returns: Nothing * Returns: Nothing
* *
* Lock status: No locks are assumed held. * Lock status: Host lock must be held
* *
* Notes: This only needs to be called if the reset is one which * Notes: This only needs to be called if the reset is one which
* originates from an unknown location. Resets originated * originates from an unknown location. Resets originated
...@@ -1656,7 +1660,7 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target) ...@@ -1656,7 +1660,7 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
shost_for_each_device(sdev, shost) { __shost_for_each_device(sdev, shost) {
if (channel == sdev->channel && if (channel == sdev->channel &&
target == sdev->id) { target == sdev->id) {
sdev->was_reset = 1; sdev->was_reset = 1;
......
...@@ -923,6 +923,22 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ...@@ -923,6 +923,22 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
{ {
struct scsi_device *sdev = q->queuedata; struct scsi_device *sdev = q->queuedata;
struct scsi_cmnd *cmd; struct scsi_cmnd *cmd;
int specials_only = 0;
if(unlikely(sdev->sdev_state != SDEV_RUNNING)) {
/* OK, we're not in a running state don't prep
* user commands */
if(sdev->sdev_state == SDEV_DEL) {
/* Device is fully deleted, no commands
* at all allowed down */
printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n",
sdev->host->host_no, sdev->id, sdev->lun);
return BLKPREP_KILL;
}
/* OK, we only allow special commands (i.e. not
* user initiated ones */
specials_only = 1;
}
/* /*
* Find the actual device driver associated with this command. * Find the actual device driver associated with this command.
...@@ -945,6 +961,14 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ...@@ -945,6 +961,14 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
} else } else
cmd = req->special; cmd = req->special;
} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
if(unlikely(specials_only)) {
printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n",
sdev->host->host_no, sdev->id, sdev->lun);
return BLKPREP_KILL;
}
/* /*
* Just check to see if the device is online. If * Just check to see if the device is online. If
* it isn't, we refuse to process ordinary commands * it isn't, we refuse to process ordinary commands
...@@ -1127,6 +1151,10 @@ static void scsi_request_fn(struct request_queue *q) ...@@ -1127,6 +1151,10 @@ static void scsi_request_fn(struct request_queue *q)
struct scsi_cmnd *cmd; struct scsi_cmnd *cmd;
struct request *req; struct request *req;
if(!get_device(&sdev->sdev_gendev))
/* We must be tearing the block queue down already */
return;
/* /*
* To start with, we keep looping until the queue is empty, or until * To start with, we keep looping until the queue is empty, or until
* the host is no longer able to accept any more requests. * the host is no longer able to accept any more requests.
...@@ -1199,7 +1227,7 @@ static void scsi_request_fn(struct request_queue *q) ...@@ -1199,7 +1227,7 @@ static void scsi_request_fn(struct request_queue *q)
} }
} }
return; goto out;
not_ready: not_ready:
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
...@@ -1217,6 +1245,12 @@ static void scsi_request_fn(struct request_queue *q) ...@@ -1217,6 +1245,12 @@ static void scsi_request_fn(struct request_queue *q)
sdev->device_busy--; sdev->device_busy--;
if(sdev->device_busy == 0) if(sdev->device_busy == 0)
blk_plug_device(q); blk_plug_device(q);
out:
/* must be careful here...if we trigger the ->remove() function
* we cannot be holding the q lock */
spin_unlock_irq(q->queue_lock);
put_device(&sdev->sdev_gendev);
spin_lock_irq(q->queue_lock);
} }
u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
......
...@@ -130,7 +130,6 @@ extern void scsi_exit_procfs(void); ...@@ -130,7 +130,6 @@ extern void scsi_exit_procfs(void);
extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
unsigned int, unsigned int, int); unsigned int, unsigned int, int);
extern void scsi_forget_host(struct Scsi_Host *); extern void scsi_forget_host(struct Scsi_Host *);
extern void scsi_free_sdev(struct scsi_device *);
extern void scsi_rescan_device(struct device *); extern void scsi_rescan_device(struct device *);
/* scsi_sysctl.c */ /* scsi_sysctl.c */
...@@ -143,7 +142,8 @@ extern void scsi_exit_sysctl(void); ...@@ -143,7 +142,8 @@ extern void scsi_exit_sysctl(void);
#endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SYSCTL */
/* scsi_sysfs.c */ /* scsi_sysfs.c */
extern int scsi_device_register(struct scsi_device *); extern void scsi_device_dev_release(struct device *);
extern int scsi_sysfs_add_sdev(struct scsi_device *);
extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_add_host(struct Scsi_Host *);
extern int scsi_sysfs_register(void); extern int scsi_sysfs_register(void);
extern void scsi_sysfs_unregister(void); extern void scsi_sysfs_unregister(void);
......
...@@ -205,6 +205,7 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, ...@@ -205,6 +205,7 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
sdev->lun = lun; sdev->lun = lun;
sdev->channel = channel; sdev->channel = channel;
sdev->online = TRUE; sdev->online = TRUE;
sdev->sdev_state = SDEV_CREATED;
INIT_LIST_HEAD(&sdev->siblings); INIT_LIST_HEAD(&sdev->siblings);
INIT_LIST_HEAD(&sdev->same_target_siblings); INIT_LIST_HEAD(&sdev->same_target_siblings);
INIT_LIST_HEAD(&sdev->cmd_list); INIT_LIST_HEAD(&sdev->cmd_list);
...@@ -236,6 +237,25 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, ...@@ -236,6 +237,25 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
goto out_free_queue; goto out_free_queue;
} }
if (get_device(&sdev->host->shost_gendev)) {
device_initialize(&sdev->sdev_gendev);
sdev->sdev_gendev.parent = &sdev->host->shost_gendev;
sdev->sdev_gendev.bus = &scsi_bus_type;
sdev->sdev_gendev.release = scsi_device_dev_release;
sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id,
sdev->lun);
class_device_initialize(&sdev->sdev_classdev);
sdev->sdev_classdev.dev = &sdev->sdev_gendev;
sdev->sdev_classdev.class = &sdev_class;
snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE,
"%d:%d:%d:%d", sdev->host->host_no,
sdev->channel, sdev->id, sdev->lun);
} else
goto out_free_queue;
/* /*
* If there are any same target siblings, add this to the * If there are any same target siblings, add this to the
* sibling list * sibling list
...@@ -272,36 +292,6 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, ...@@ -272,36 +292,6 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
return NULL; return NULL;
} }
/**
* scsi_free_sdev - cleanup and free a scsi_device
* @sdev: cleanup and free this scsi_device
*
* Description:
* Undo the actions in scsi_alloc_sdev, including removing @sdev from
* the list, and freeing @sdev.
**/
void scsi_free_sdev(struct scsi_device *sdev)
{
unsigned long flags;
spin_lock_irqsave(sdev->host->host_lock, flags);
list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
if (sdev->request_queue)
scsi_free_queue(sdev->request_queue);
spin_lock_irqsave(sdev->host->host_lock, flags);
list_del(&sdev->starved_entry);
if (sdev->single_lun && --sdev->sdev_target->starget_refcnt == 0)
kfree(sdev->sdev_target);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
kfree(sdev->inquiry);
kfree(sdev);
}
/** /**
* scsi_probe_lun - probe a single LUN using a SCSI INQUIRY * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
* @sreq: used to send the INQUIRY * @sreq: used to send the INQUIRY
...@@ -642,7 +632,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) ...@@ -642,7 +632,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
* register it and tell the rest of the kernel * register it and tell the rest of the kernel
* about it. * about it.
*/ */
scsi_device_register(sdev); scsi_sysfs_add_sdev(sdev);
return SCSI_SCAN_LUN_PRESENT; return SCSI_SCAN_LUN_PRESENT;
} }
...@@ -748,8 +738,11 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host, ...@@ -748,8 +738,11 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
if (res == SCSI_SCAN_LUN_PRESENT) { if (res == SCSI_SCAN_LUN_PRESENT) {
if (sdevp) if (sdevp)
*sdevp = sdev; *sdevp = sdev;
} else } else {
scsi_free_sdev(sdev); if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
put_device(&sdev->sdev_gendev);
}
out: out:
return res; return res;
} }
...@@ -1301,5 +1294,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) ...@@ -1301,5 +1294,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
void scsi_free_host_dev(struct scsi_device *sdev) void scsi_free_host_dev(struct scsi_device *sdev)
{ {
BUG_ON(sdev->id != sdev->host->this_id); BUG_ON(sdev->id != sdev->host->this_id);
scsi_free_sdev(sdev);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
put_device(&sdev->sdev_gendev);
} }
...@@ -115,14 +115,29 @@ static void scsi_device_cls_release(struct class_device *class_dev) ...@@ -115,14 +115,29 @@ static void scsi_device_cls_release(struct class_device *class_dev)
put_device(&sdev->sdev_gendev); put_device(&sdev->sdev_gendev);
} }
static void scsi_device_dev_release(struct device *dev) void scsi_device_dev_release(struct device *dev)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
struct device *parent; struct device *parent;
unsigned long flags;
parent = dev->parent; parent = dev->parent;
sdev = to_scsi_device(dev); sdev = to_scsi_device(dev);
scsi_free_sdev(sdev);
spin_lock_irqsave(sdev->host->host_lock, flags);
list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings);
list_del(&sdev->starved_entry);
if (sdev->single_lun && --sdev->sdev_target->starget_refcnt == 0)
kfree(sdev->sdev_target);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
if (sdev->request_queue)
scsi_free_queue(sdev->request_queue);
kfree(sdev->inquiry);
kfree(sdev);
put_device(parent); put_device(parent);
} }
...@@ -321,29 +336,20 @@ static int attr_add(struct device *dev, struct device_attribute *attr) ...@@ -321,29 +336,20 @@ static int attr_add(struct device *dev, struct device_attribute *attr)
} }
/** /**
* scsi_device_register - register a scsi device with the scsi bus * scsi_sysfs_add_sdev - add scsi device to sysfs
* @sdev: scsi_device to register * @sdev: scsi_device to add
* *
* Return value: * Return value:
* 0 on Success / non-zero on Failure * 0 on Success / non-zero on Failure
**/ **/
int scsi_device_register(struct scsi_device *sdev) int scsi_sysfs_add_sdev(struct scsi_device *sdev)
{ {
int error = 0, i; int error = -EINVAL, i;
set_bit(SDEV_ADD, &sdev->sdev_state); if (sdev->sdev_state != SDEV_CREATED)
device_initialize(&sdev->sdev_gendev); return error;
sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->sdev_state = SDEV_RUNNING;
sdev->sdev_gendev.parent = &sdev->host->shost_gendev;
sdev->sdev_gendev.bus = &scsi_bus_type;
sdev->sdev_gendev.release = scsi_device_dev_release;
class_device_initialize(&sdev->sdev_classdev);
sdev->sdev_classdev.dev = &sdev->sdev_gendev;
sdev->sdev_classdev.class = &sdev_class;
snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, "%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
error = device_add(&sdev->sdev_gendev); error = device_add(&sdev->sdev_gendev);
if (error) { if (error) {
...@@ -351,8 +357,6 @@ int scsi_device_register(struct scsi_device *sdev) ...@@ -351,8 +357,6 @@ int scsi_device_register(struct scsi_device *sdev)
return error; return error;
} }
get_device(sdev->sdev_gendev.parent);
error = class_device_add(&sdev->sdev_classdev); error = class_device_add(&sdev->sdev_classdev);
if (error) { if (error) {
printk(KERN_INFO "error 2\n"); printk(KERN_INFO "error 2\n");
...@@ -384,8 +388,11 @@ int scsi_device_register(struct scsi_device *sdev) ...@@ -384,8 +388,11 @@ int scsi_device_register(struct scsi_device *sdev)
return error; return error;
clean_device: clean_device:
sdev->sdev_state = SDEV_CANCEL;
device_del(&sdev->sdev_gendev); device_del(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev); put_device(&sdev->sdev_gendev);
return error; return error;
} }
...@@ -396,12 +403,14 @@ int scsi_device_register(struct scsi_device *sdev) ...@@ -396,12 +403,14 @@ int scsi_device_register(struct scsi_device *sdev)
**/ **/
void scsi_remove_device(struct scsi_device *sdev) void scsi_remove_device(struct scsi_device *sdev)
{ {
class_device_unregister(&sdev->sdev_classdev); if (sdev->sdev_state == SDEV_RUNNING || sdev->sdev_state == SDEV_CANCEL) {
set_bit(SDEV_DEL, &sdev->sdev_state); sdev->sdev_state = SDEV_DEL;
if (sdev->host->hostt->slave_destroy) class_device_unregister(&sdev->sdev_classdev);
sdev->host->hostt->slave_destroy(sdev); device_del(&sdev->sdev_gendev);
device_del(&sdev->sdev_gendev); if (sdev->host->hostt->slave_destroy)
put_device(&sdev->sdev_gendev); sdev->host->hostt->slave_destroy(sdev);
put_device(&sdev->sdev_gendev);
}
} }
int scsi_register_driver(struct device_driver *drv) int scsi_register_driver(struct device_driver *drv)
......
...@@ -70,8 +70,8 @@ struct fb_info fb_info; ...@@ -70,8 +70,8 @@ struct fb_info fb_info;
struct fb_fix_screeninfo igafb_fix __initdata = { struct fb_fix_screeninfo igafb_fix __initdata = {
.id = "IGA 1682", .id = "IGA 1682",
.type = FB_TYPE_PACKED_PIXELS; .type = FB_TYPE_PACKED_PIXELS,
.mmio_len = 1000; .mmio_len = 1000
}; };
struct fb_var_screeninfo default_var = { struct fb_var_screeninfo default_var = {
...@@ -149,7 +149,7 @@ struct fb_var_screeninfo default_var_1280x1024 __initdata = { ...@@ -149,7 +149,7 @@ struct fb_var_screeninfo default_var_1280x1024 __initdata = {
.xres = 1280, .xres = 1280,
.yres = 1024, .yres = 1024,
.xres_virtual = 1280, .xres_virtual = 1280,
.yres_virtaul = 1024, .yres_virtual = 1024,
.bits_per_pixel = 8, .bits_per_pixel = 8,
.red = {0, 8, 0 }, .red = {0, 8, 0 },
.green = {0, 8, 0 }, .green = {0, 8, 0 },
...@@ -300,17 +300,17 @@ static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -300,17 +300,17 @@ static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (regno < 16) { if (regno < 16) {
switch (info->var.bits_per_pixel) { switch (info->var.bits_per_pixel) {
case 16: case 16:
info->pseudo_palette[regno] = ((u16*)(info->pseudo_palette))[regno] =
(regno << 10) | (regno << 5) | regno; (regno << 10) | (regno << 5) | regno;
break; break;
case 24: case 24:
info->pseudo_palette[regno] = ((u32*)(info->pseudo_palette))[regno] =
(regno << 16) | (regno << 8) | regno; (regno << 16) | (regno << 8) | regno;
break; break;
case 32: case 32:
{ int i; { int i;
i = (regno << 8) | regno; i = (regno << 8) | regno;
info->pseudo_palette[regno] = (i << 16) | i; ((u32*)(info->pseudo_palette))[regno] = (i << 16) | i;
} }
break; break;
} }
...@@ -359,7 +359,7 @@ static int __init iga_init(struct fb_info *info, struct iga_par *par) ...@@ -359,7 +359,7 @@ static int __init iga_init(struct fb_info *info, struct iga_par *par)
info->fbops = &igafb_ops; info->fbops = &igafb_ops;
info->flags = FBINFO_FLAG_DEFAULT; info->flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(info->cmap, video_cmap_len, 0); fb_alloc_cmap(&info->cmap, video_cmap_len, 0);
if (register_framebuffer(info) < 0) if (register_framebuffer(info) < 0)
return 0; return 0;
......
...@@ -1415,6 +1415,10 @@ void jfs_flush_journal(struct jfs_log *log, int wait) ...@@ -1415,6 +1415,10 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
int i; int i;
struct tblock *target; struct tblock *target;
/* jfs_write_inode may call us during read-only mount */
if (!log)
return;
jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait); jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait);
LOGGC_LOCK(log); LOGGC_LOCK(log);
......
...@@ -198,6 +198,7 @@ void proc_tty_register_driver(struct tty_driver *driver) ...@@ -198,6 +198,7 @@ void proc_tty_register_driver(struct tty_driver *driver)
return; return;
ent->read_proc = driver->read_proc; ent->read_proc = driver->read_proc;
ent->write_proc = driver->write_proc; ent->write_proc = driver->write_proc;
ent->owner = driver->owner;
ent->data = driver; ent->data = driver;
driver->proc_entry = ent; driver->proc_entry = ent;
......
...@@ -496,6 +496,6 @@ extern void update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, p ...@@ -496,6 +496,6 @@ extern void update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, p
/* These tell get_user_pages() that the first gate page is accessible from user-level. */ /* These tell get_user_pages() that the first gate page is accessible from user-level. */
#define FIXADDR_USER_START GATE_ADDR #define FIXADDR_USER_START GATE_ADDR
#define FIXADDR_USER_END (GATE_ADDR + 2*PAGE_SIZE) #define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE)
#endif /* _ASM_IA64_PGTABLE_H */ #endif /* _ASM_IA64_PGTABLE_H */
...@@ -310,6 +310,7 @@ struct ata_port { ...@@ -310,6 +310,7 @@ struct ata_port {
struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
u8 ctl; /* cache of ATA control register */ u8 ctl; /* cache of ATA control register */
u8 last_ctl; /* Cache last written value */
unsigned int bus_state; unsigned int bus_state;
unsigned int port_state; unsigned int port_state;
unsigned int pio_mask; unsigned int pio_mask;
...@@ -522,12 +523,12 @@ static inline u8 ata_irq_on(struct ata_port *ap) ...@@ -522,12 +523,12 @@ static inline u8 ata_irq_on(struct ata_port *ap)
struct ata_ioports *ioaddr = &ap->ioaddr; struct ata_ioports *ioaddr = &ap->ioaddr;
ap->ctl &= ~ATA_NIEN; ap->ctl &= ~ATA_NIEN;
ap->last_ctl = ap->ctl;
if (ap->flags & ATA_FLAG_MMIO) if (ap->flags & ATA_FLAG_MMIO)
writeb(ap->ctl, ioaddr->ctl_addr); writeb(ap->ctl, ioaddr->ctl_addr);
else else
outb(ap->ctl, ioaddr->ctl_addr); outb(ap->ctl, ioaddr->ctl_addr);
return ata_wait_idle(ap); return ata_wait_idle(ap);
} }
......
...@@ -917,6 +917,7 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) ...@@ -917,6 +917,7 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{ {
int err = 0; int err = 0;
int skb_len;
/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
number of warnings when compiling with -W --ANK number of warnings when compiling with -W --ANK
...@@ -937,9 +938,18 @@ static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -937,9 +938,18 @@ static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
skb->dev = NULL; skb->dev = NULL;
skb_set_owner_r(skb, sk); skb_set_owner_r(skb, sk);
/* Cache the SKB length before we tack it onto the receive
* queue. Once it is added it no longer belongs to us and
* may be freed by other threads of control pulling packets
* from the queue.
*/
skb_len = skb->len;
skb_queue_tail(&sk->sk_receive_queue, skb); skb_queue_tail(&sk->sk_receive_queue, skb);
if (!sock_flag(sk, SOCK_DEAD)) if (!sock_flag(sk, SOCK_DEAD))
sk->sk_data_ready(sk, skb->len); sk->sk_data_ready(sk, skb_len);
out: out:
return err; return err;
} }
......
...@@ -14,11 +14,15 @@ struct scsi_mode_data; ...@@ -14,11 +14,15 @@ struct scsi_mode_data;
/* /*
* sdev state * sdev state
*/ */
enum { enum scsi_device_state {
SDEV_ADD, SDEV_CREATED, /* device created but not added to sysfs
SDEV_DEL, * Only internal commands allowed (for inq) */
SDEV_CANCEL, SDEV_RUNNING, /* device properly configured
SDEV_RECOVERY, * All commands allowed */
SDEV_CANCEL, /* beginning to delete device
* Only error handler commands allowed */
SDEV_DEL, /* device deleted
* no commands allowed */
}; };
struct scsi_device { struct scsi_device {
...@@ -99,7 +103,7 @@ struct scsi_device { ...@@ -99,7 +103,7 @@ struct scsi_device {
struct device sdev_gendev; struct device sdev_gendev;
struct class_device sdev_classdev; struct class_device sdev_classdev;
unsigned long sdev_state; enum scsi_device_state sdev_state;
}; };
#define to_scsi_device(d) \ #define to_scsi_device(d) \
container_of(d, struct scsi_device, sdev_gendev) container_of(d, struct scsi_device, sdev_gendev)
......
...@@ -1014,6 +1014,7 @@ struct task_struct *copy_process(unsigned long clone_flags, ...@@ -1014,6 +1014,7 @@ struct task_struct *copy_process(unsigned long clone_flags,
if (current->signal->group_exit) { if (current->signal->group_exit) {
spin_unlock(&current->sighand->siglock); spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock); write_unlock_irq(&tasklist_lock);
retval = -EAGAIN;
goto bad_fork_cleanup_namespace; goto bad_fork_cleanup_namespace;
} }
p->tgid = current->tgid; p->tgid = current->tgid;
......
...@@ -32,7 +32,7 @@ int (*br_should_route_hook) (struct sk_buff **pskb) = NULL; ...@@ -32,7 +32,7 @@ int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
static int __init br_init(void) static int __init br_init(void)
{ {
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER) #ifdef CONFIG_BRIDGE_NETFILTER
if (br_netfilter_init()) if (br_netfilter_init())
return 1; return 1;
#endif #endif
...@@ -50,7 +50,7 @@ static int __init br_init(void) ...@@ -50,7 +50,7 @@ static int __init br_init(void)
static void __exit br_deinit(void) static void __exit br_deinit(void)
{ {
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER) #ifdef CONFIG_BRIDGE_NETFILTER
br_netfilter_fini(); br_netfilter_fini();
#endif #endif
unregister_netdevice_notifier(&br_device_notifier); unregister_netdevice_notifier(&br_device_notifier);
......
...@@ -1041,12 +1041,15 @@ static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet ...@@ -1041,12 +1041,15 @@ static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
if (!sk) if (!sk)
goto drop; goto drop;
return ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb, if (ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb,
hdr->port); hdr->port))
goto drop;
return 0;
drop: drop:
kfree_skb(skb); kfree_skb(skb);
return 0; return NET_RX_DROP;
} }
static struct packet_type econet_packet_type = { static struct packet_type econet_packet_type = {
......
...@@ -1924,9 +1924,13 @@ static int addrconf_ifdown(struct net_device *dev, int how) ...@@ -1924,9 +1924,13 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_unlock_bh(&addrconf_hash_lock); write_unlock_bh(&addrconf_hash_lock);
} }
/* Step 3: clear address list */
write_lock_bh(&idev->lock); write_lock_bh(&idev->lock);
/* Step 3: clear flags for stateless addrconf */
if (how != 1)
idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
/* Step 4: clear address list */
#ifdef CONFIG_IPV6_PRIVACY #ifdef CONFIG_IPV6_PRIVACY
if (how == 1 && del_timer(&idev->regen_timer)) if (how == 1 && del_timer(&idev->regen_timer))
in6_dev_put(idev); in6_dev_put(idev);
...@@ -1962,7 +1966,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) ...@@ -1962,7 +1966,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
} }
write_unlock_bh(&idev->lock); write_unlock_bh(&idev->lock);
/* Step 4: Discard multicast list */ /* Step 5: Discard multicast list */
if (how == 1) if (how == 1)
ipv6_mc_destroy_dev(idev); ipv6_mc_destroy_dev(idev);
......
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/snmp.h> #include <net/snmp.h>
...@@ -1270,6 +1273,7 @@ static void mld_sendpack(struct sk_buff *skb) ...@@ -1270,6 +1273,7 @@ static void mld_sendpack(struct sk_buff *skb)
struct mld2_report *pmr = (struct mld2_report *)skb->h.raw; struct mld2_report *pmr = (struct mld2_report *)skb->h.raw;
int payload_len, mldlen; int payload_len, mldlen;
struct inet6_dev *idev = in6_dev_get(skb->dev); struct inet6_dev *idev = in6_dev_get(skb->dev);
int err;
payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h - payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
sizeof(struct ipv6hdr); sizeof(struct ipv6hdr);
...@@ -1278,8 +1282,10 @@ static void mld_sendpack(struct sk_buff *skb) ...@@ -1278,8 +1282,10 @@ static void mld_sendpack(struct sk_buff *skb)
pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
dev_queue_xmit(skb); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
ICMP6_INC_STATS(idev,Icmp6OutMsgs); dev_queue_xmit);
if (!err)
ICMP6_INC_STATS(idev,Icmp6OutMsgs);
if (likely(idev != NULL)) if (likely(idev != NULL))
in6_dev_put(idev); in6_dev_put(idev);
} }
...@@ -1608,12 +1614,15 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) ...@@ -1608,12 +1614,15 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
idev = in6_dev_get(skb->dev); idev = in6_dev_get(skb->dev);
dev_queue_xmit(skb); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
if (type == ICMPV6_MGM_REDUCTION) dev_queue_xmit);
ICMP6_INC_STATS(idev, Icmp6OutGroupMembReductions); if (!err) {
else if (type == ICMPV6_MGM_REDUCTION)
ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses); ICMP6_INC_STATS(idev, Icmp6OutGroupMembReductions);
ICMP6_INC_STATS(idev, Icmp6OutMsgs); else
ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
ICMP6_INC_STATS(idev, Icmp6OutMsgs);
}
if (likely(idev != NULL)) if (likely(idev != NULL))
in6_dev_put(idev); in6_dev_put(idev);
......
...@@ -859,10 +859,10 @@ static int irttp_udata_indication(void *instance, void *sap, ...@@ -859,10 +859,10 @@ static int irttp_udata_indication(void *instance, void *sap,
err = self->notify.udata_indication(self->notify.instance, err = self->notify.udata_indication(self->notify.instance,
self,skb); self,skb);
/* Same comment as in irttp_do_data_indication() */ /* Same comment as in irttp_do_data_indication() */
if (err != -ENOMEM) if (!err)
return 0; return 0;
} }
/* Either no handler, or -ENOMEM */ /* Either no handler, or handler returns an error */
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
...@@ -1620,7 +1620,7 @@ void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb) ...@@ -1620,7 +1620,7 @@ void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb)
* be difficult, so it can instead just refuse to eat it and just * be difficult, so it can instead just refuse to eat it and just
* give an error back * give an error back
*/ */
if (err == -ENOMEM) { if (err) {
IRDA_DEBUG(0, "%s() requeueing skb!\n", __FUNCTION__); IRDA_DEBUG(0, "%s() requeueing skb!\n", __FUNCTION__);
/* Make sure we take a break */ /* Make sure we take a break */
......
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