Commit 9415ebfa authored by Dave Kleikamp's avatar Dave Kleikamp

manual merge

parents 0f2c31e8 e689bf58
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 0
EXTRAVERSION = -test10
EXTRAVERSION = -test11
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
......
......@@ -1910,7 +1910,7 @@ unw_unwind_to_user (struct unw_frame_info *info)
__FUNCTION__, ip);
return -1;
}
if (ip < GATE_ADDR)
if (ip < FIXADDR_USER_END)
return 0;
}
unw_get_ip(info, &ip);
......
......@@ -472,6 +472,15 @@ extern __inline__ unsigned long do_gettimeoffset(void)
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.
* There are just too many variables that need to be protected
* 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,
if (csraddr < CSR_TOPOLOGY_MAP) {
if (csraddr + length > CSR_CONFIG_ROM + host->csr.rom_size) {
spin_unlock_irqrestore(&host->csr.lock, flags);
return RCODE_ADDRESS_ERROR;
}
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,
return NULL;
}
hi = kmalloc(sizeof(*hi) + data_size, GFP_KERNEL);
hi = kmalloc(sizeof(*hi) + data_size, GFP_ATOMIC);
if (!hi)
return NULL;
......
......@@ -92,7 +92,7 @@ void hpsb_unref_host(struct hpsb_host *host)
down(&hpsb_hosts_lock);
if (atomic_dec_and_test(&host->refcount) && host->is_shutdown)
kfree(host);
device_unregister(&host->device);
up(&hpsb_hosts_lock);
}
......
......@@ -137,7 +137,7 @@ int hpsb_get_tlabel(struct hpsb_packet *packet)
tp = &packet->host->tpool[packet->node_id & NODE_MASK];
if (in_interrupt() || in_atomic()) {
if (irqs_disabled() || in_atomic()) {
if (down_trylock(&tp->count))
return 1;
} else {
......
......@@ -13,9 +13,6 @@
#include <asm/byteorder.h>
/* The great kdev_t changeover in 2.5.x */
#include <linux/kdev_t.h>
/* Transaction Label handling */
struct hpsb_tlabel_pool {
DECLARE_BITMAP(pool, 64);
......
......@@ -420,6 +420,12 @@ static void nodemgr_release_ne(struct device *dev)
}
static void nodemgr_release_host(struct device *dev)
{
kfree(container_of(dev, struct hpsb_host, device));
}
static void nodemgr_remove_ud(struct unit_directory *ud)
{
struct device *dev = &ud->device;
......@@ -513,6 +519,7 @@ static struct device nodemgr_dev_template_ne = {
static struct device nodemgr_dev_template_host = {
.bus = &ieee1394_bus_type,
.release = nodemgr_release_host,
.driver = &nodemgr_driver_host,
.driver_data = &nodemgr_driverdata_host,
};
......@@ -676,8 +683,27 @@ static struct node_entry *nodemgr_scan_root_directory
}
static void nodemgr_process_config_rom(struct host_info *hi,
struct node_entry *ne, quadlet_t busoptions);
static void nodemgr_update_bus_options(struct node_entry *ne,
quadlet_t busoptions)
{
ne->busopt.irmc = (busoptions >> 31) & 1;
ne->busopt.cmc = (busoptions >> 30) & 1;
ne->busopt.isc = (busoptions >> 29) & 1;
ne->busopt.bmc = (busoptions >> 28) & 1;
ne->busopt.pmc = (busoptions >> 27) & 1;
ne->busopt.cyc_clk_acc = (busoptions >> 16) & 0xff;
ne->busopt.max_rec = 1 << (((busoptions >> 12) & 0xf) + 1);
ne->busopt.generation = (busoptions >> 4) & 0xf;
ne->busopt.lnkspd = busoptions & 0x7;
HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
"cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d",
busoptions, ne->busopt.irmc, ne->busopt.cmc,
ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc,
ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
ne->busopt.generation, ne->busopt.lnkspd);
}
static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoptions,
struct host_info *hi, nodeid_t nodeid,
......@@ -694,6 +720,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption
ne->host = host;
ne->nodeid = nodeid;
ne->generation = generation;
ne->needs_probe = 1;
ne->guid = guid;
ne->guid_vendor_id = (guid >> 40) & 0xffffff;
......@@ -711,7 +738,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption
device_create_file(&ne->device, &dev_attr_ne_guid_vendor_oui);
nodemgr_create_ne_dev_files(ne);
nodemgr_process_config_rom (hi, ne, busoptions);
nodemgr_update_bus_options(ne, busoptions);
HPSB_DEBUG("%s added: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
(host->node_id == nodeid) ? "Host" : "Node",
......@@ -806,6 +833,7 @@ static struct unit_directory *nodemgr_scan_unit_directory
if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad))
return NULL;
length = CONFIG_ROM_DIRECTORY_LENGTH(quad) ;
address += 4;
......@@ -1055,7 +1083,7 @@ static struct unit_directory *nodemgr_process_unit_directory
return ud;
unit_directory_error:
unit_directory_error:
if (ud != NULL)
kfree(ud);
return NULL;
......@@ -1069,6 +1097,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
int length;
unsigned int ud_id = 0;
device_remove_file(&ne->device, &dev_attr_ne_vendor_oui);
address = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation,
......@@ -1129,6 +1159,9 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
break;
}
}
if (ne->vendor_oui)
device_create_file(&ne->device, &dev_attr_ne_vendor_oui);
}
#ifdef CONFIG_HOTPLUG
......@@ -1221,34 +1254,6 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
driver_unregister(&driver->driver);
}
static void nodemgr_process_config_rom(struct host_info *hi,
struct node_entry *ne, quadlet_t busoptions)
{
ne->busopt.irmc = (busoptions >> 31) & 1;
ne->busopt.cmc = (busoptions >> 30) & 1;
ne->busopt.isc = (busoptions >> 29) & 1;
ne->busopt.bmc = (busoptions >> 28) & 1;
ne->busopt.pmc = (busoptions >> 27) & 1;
ne->busopt.cyc_clk_acc = (busoptions >> 16) & 0xff;
ne->busopt.max_rec = 1 << (((busoptions >> 12) & 0xf) + 1);
ne->busopt.generation = (busoptions >> 4) & 0xf;
ne->busopt.lnkspd = busoptions & 0x7;
HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
"cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d",
busoptions, ne->busopt.irmc, ne->busopt.cmc,
ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc,
ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
ne->busopt.generation, ne->busopt.lnkspd);
device_remove_file(&ne->device, &dev_attr_ne_vendor_oui);
nodemgr_process_root_directory(hi, ne);
if (ne->vendor_oui)
device_create_file(&ne->device, &dev_attr_ne_vendor_oui);
}
/* Searches the list of ud's that match a ne as the parent. If the ud has
* a driver associated with it, we call that driver's update function
......@@ -1303,18 +1308,14 @@ static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions,
* unregister all the unit directories. */
nodemgr_remove_node_uds(ne);
/* With all the ud's gone, mark the generation current,
* this way the probe will succeed. */
ne->generation = generation;
nodemgr_update_bus_options(ne, busoptions);
/* This will re-register our unitdir's */
nodemgr_process_config_rom (hi, ne, busoptions);
} else
ne->generation = generation;
/* Mark the node as new, so it gets re-probed */
ne->needs_probe = 1;
}
/* Update unit_dirs with attached drivers */
bus_for_each_dev(&ieee1394_bus_type, NULL, ne,
nodemgr_driver_search_cb);
/* Mark the node current */
ne->generation = generation;
}
static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned int generation,
......@@ -1385,10 +1386,8 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
}
/* This is where we probe the nodes for their information and provided
* features. */
static void nodemgr_node_probe_one(struct host_info *hi,
nodeid_t nodeid, int generation)
static void nodemgr_node_scan_one(struct host_info *hi,
nodeid_t nodeid, int generation)
{
struct hpsb_host *host = hi->host;
struct node_entry *ne;
......@@ -1411,7 +1410,7 @@ static void nodemgr_node_probe_one(struct host_info *hi,
* shouldn't be held responsible, so we'll allow it with a
* warning. */
HPSB_WARN("Node " NODE_BUS_FMT " has invalid busID magic [0x%08x]",
NODE_BUS_ARGS(host, nodeid), buffer[1]);
NODE_BUS_ARGS(host, nodeid), buffer[1]);
}
guid = ((u64)buffer[3] << 32) | buffer[4];
......@@ -1453,24 +1452,84 @@ static int nodemgr_remove_node(struct device *dev, void *__data)
return 0;
}
struct ne_cb_data_struct {
struct host_info *hi;
struct node_entry *ne;
};
static void nodemgr_node_probe(struct host_info *hi, int generation)
static int nodemgr_probe_ne_cb(struct device *dev, void *__data)
{
int count;
struct hpsb_host *host = hi->host;
struct selfid *sid = (struct selfid *)host->topology_map;
nodeid_t nodeid = LOCAL_BUS;
struct ne_cb_data_struct *ne_cb_data = __data;
struct host_info *hi = ne_cb_data->hi;
struct node_entry *ne;
/* Scan each node on the bus */
for (count = host->selfid_count; count; count--, sid++) {
if (sid->extended)
continue;
if (dev->driver_data != &nodemgr_driverdata_ne)
return 0;
if (!sid->link_active) {
nodeid++;
continue;
ne = ne_cb_data->ne = container_of(dev, struct node_entry, device);
if (ne->host != hi->host)
return 0;
/* We can't call nodemgr_process_root_directory() here because
* that can call device_register. Since this callback is under a
* rwsem, the device_register would deadlock. So, we signal back
* to the callback, and process things there. */
if (ne->needs_probe) {
ne->needs_probe = 0;
return 1;
} else {
/* Update unit_dirs with attached drivers */
bus_for_each_dev(&ieee1394_bus_type, NULL, ne,
nodemgr_driver_search_cb);
}
return 0;
}
static void nodemgr_node_scan(struct host_info *hi, int generation)
{
int count;
struct hpsb_host *host = hi->host;
struct selfid *sid = (struct selfid *)host->topology_map;
nodeid_t nodeid = LOCAL_BUS;
/* Scan each node on the bus */
for (count = host->selfid_count; count; count--, sid++) {
if (sid->extended)
continue;
if (!sid->link_active) {
nodeid++;
continue;
}
nodemgr_node_scan_one(hi, nodeid++, generation);
}
}
static void nodemgr_node_probe(struct host_info *hi, int generation)
{
struct hpsb_host *host = hi->host;
struct ne_cb_data_struct ne_cb_data;
ne_cb_data.hi = hi;
ne_cb_data.ne = NULL;
/* Do some processing of the nodes we've probed. This pulls them
* into the sysfs layer if needed, and can result in processing of
* unit-directories, or just updating the node and it's
* unit-directories. */
while (bus_for_each_dev(&ieee1394_bus_type, ne_cb_data.ne ? &ne_cb_data.ne->device : NULL,
&ne_cb_data, nodemgr_probe_ne_cb)) {
/* If we get in here, we've got a node that needs it's
* unit directories processed. */
struct device *dev = get_device(&ne_cb_data.ne->device);
if (dev) {
nodemgr_process_root_directory(hi, ne_cb_data.ne);
put_device(dev);
}
nodemgr_node_probe_one(hi, nodeid++, generation);
}
/* If we had a bus reset while we were scanning the bus, it is
......@@ -1513,12 +1572,12 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other
* nodes of the broadcast channel. (Really we're only setting the validity
* bit). Other IRM responsibilities go in here as well. */
static void nodemgr_do_irm_duties(struct hpsb_host *host)
static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
{
quadlet_t bc;
if (!host->is_irm)
return;
return 1;
host->csr.broadcast_channel |= 0x40000000; /* set validity bit */
......@@ -1541,10 +1600,21 @@ static void nodemgr_do_irm_duties(struct hpsb_host *host)
else {
HPSB_DEBUG("The root node is not cycle master capable; "
"selecting a new root node and resetting...");
if (cycles >= 5) {
/* Oh screw it! Just leave the bus as it is */
HPSB_DEBUG("Stopping reset loop for IRM sanity");
return 1;
}
hpsb_send_phy_config(host, NODEID_TO_NODE(host->node_id), -1);
hpsb_reset_bus(host, LONG_RESET_FORCE_ROOT);
return 0;
}
}
return 1;
}
/* We need to ensure that if we are not the IRM, that the IRM node is capable of
......@@ -1608,8 +1678,10 @@ static int nodemgr_host_thread(void *__hi)
* to make sure things settle down. */
for (i = 0; i < 4 ; i++) {
set_current_state(TASK_INTERRUPTIBLE);
if (schedule_timeout(HZ/16))
if (schedule_timeout(HZ/16)) {
up(&nodemgr_serialize);
goto caught_signal;
}
/* Now get the generation in which the node ID's we collect
* are valid. During the bus scan we will use this generation
......@@ -1624,16 +1696,28 @@ static int nodemgr_host_thread(void *__hi)
i = 0;
}
if (!nodemgr_check_irm_capability(host, reset_cycles++)) {
/* Do nothing, we are resetting */
if (!nodemgr_check_irm_capability(host, reset_cycles)) {
reset_cycles++;
up(&nodemgr_serialize);
continue;
}
/* Scan our nodes to get the bus options and create node
* entries. This does not do the sysfs stuff, since that
* would trigger hotplug callbacks and such, which is a
* bad idea at this point. */
nodemgr_node_scan(hi, generation);
if (!nodemgr_do_irm_duties(host, reset_cycles)) {
reset_cycles++;
up(&nodemgr_serialize);
continue;
}
reset_cycles = 0;
/* This actually does the full probe, with sysfs
* registration. */
nodemgr_node_probe(hi, generation);
nodemgr_do_irm_duties(host);
/* Update some of our sysfs symlinks */
nodemgr_update_host_dev_links(host);
......@@ -1778,7 +1862,6 @@ static void nodemgr_remove_host(struct hpsb_host *host)
kill_proc(hi->pid, SIGTERM, 1);
wait_for_completion(&hi->exited);
nodemgr_remove_host_dev(&host->device);
device_unregister(&host->device);
}
} else
HPSB_ERR("NodeMgr: host %s does not exist, cannot remove",
......
......@@ -130,6 +130,7 @@ struct node_entry {
struct hpsb_host *host; /* Host this node is attached to */
nodeid_t nodeid; /* NodeID */
struct bus_options busopt; /* Bus Options */
int needs_probe;
unsigned int generation; /* Synced with hpsb generation */
/* 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)
return 0;
out3:
release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT);
release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT);
out2:
release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT);
out1:
......
......@@ -352,7 +352,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
if (!__pppoe_xmit( relay_po->sk, skb))
goto abort_put;
} else {
sock_queue_rcv_skb(sk, skb);
if (sock_queue_rcv_skb(sk, skb))
goto abort_kfree;
}
return NET_RX_SUCCESS;
......
......@@ -133,7 +133,11 @@ void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
struct ata_ioports *ioaddr = &ap->ioaddr;
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)) {
outb(tf->hob_feature, ioaddr->error_addr);
......@@ -187,7 +191,11 @@ void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
struct ata_ioports *ioaddr = &ap->ioaddr;
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)) {
writeb(tf->hob_feature, (void *) ioaddr->error_addr);
......@@ -1281,9 +1289,9 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
/* software reset. causes dev0 to be selected */
if (ap->flags & ATA_FLAG_MMIO) {
writeb(ap->ctl, ioaddr->ctl_addr);
udelay(10); /* FIXME: flush */
udelay(20); /* FIXME: flush */
writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
udelay(10); /* FIXME: flush */
udelay(20); /* FIXME: flush */
writeb(ap->ctl, ioaddr->ctl_addr);
} else {
outb(ap->ctl, ioaddr->ctl_addr);
......@@ -2755,6 +2763,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
ap->cbl = ATA_CBL_NONE;
ap->device[0].flags = ATA_DFLAG_MASTER;
ap->active_tag = ATA_TAG_POISON;
ap->last_ctl = 0xFF;
/* ata_engine init */
ap->eng.flags = 0;
......
......@@ -26,7 +26,7 @@
#define __LIBATA_H__
#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_port *ap;
......
......@@ -213,6 +213,8 @@ static struct pci_device_id pdc_sata_pci_tbl[] = {
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
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,
board_20319 },
{ PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
......
......@@ -44,7 +44,7 @@
#endif /* CONFIG_ALL_PPC */
#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)
......@@ -69,8 +69,11 @@ static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
struct ata_ioports *ioaddr = &ap->ioaddr;
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)) {
writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->error_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
rc = -ENODEV;
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->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SRST | ATA_FLAG_MMIO;
probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO;
probe_ent->port_ops = &k2_sata_ops;
probe_ent->n_ports = 2;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
probe_ent->n_ports = 2;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
probe_ent->mmio_base = mmio_base;
/*
......
......@@ -367,6 +367,16 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
unsigned long timeout;
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. */
/* XXX(hch): this is racy */
if (++serial_number == 0)
......@@ -893,7 +903,7 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
*/
int scsi_device_get(struct scsi_device *sdev)
{
if (test_bit(SDEV_DEL, &sdev->sdev_state))
if (sdev->sdev_state == SDEV_DEL)
return -ENXIO;
if (!get_device(&sdev->sdev_gendev))
return -ENXIO;
......@@ -1015,7 +1025,7 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
struct list_head *lh, *lh_sf;
unsigned long flags;
set_bit(SDEV_CANCEL, &sdev->sdev_state);
sdev->sdev_state = SDEV_CANCEL;
spin_lock_irqsave(&sdev->list_lock, flags);
list_for_each_entry(scmd, &sdev->cmd_list, list) {
......
......@@ -911,7 +911,9 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
if (rtn == SUCCESS) {
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);
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}
return rtn;
......@@ -940,7 +942,9 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
if (rtn == SUCCESS) {
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);
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}
return rtn;
......@@ -1608,7 +1612,7 @@ int scsi_error_handler(void *data)
*
* 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
* originates from an unknown location. Resets originated
......@@ -1622,7 +1626,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
{
struct scsi_device *sdev;
shost_for_each_device(sdev, shost) {
__shost_for_each_device(sdev, shost) {
if (channel == sdev->channel) {
sdev->was_reset = 1;
sdev->expecting_cc_ua = 1;
......@@ -1642,7 +1646,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
*
* 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
* originates from an unknown location. Resets originated
......@@ -1656,7 +1660,7 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
{
struct scsi_device *sdev;
shost_for_each_device(sdev, shost) {
__shost_for_each_device(sdev, shost) {
if (channel == sdev->channel &&
target == sdev->id) {
sdev->was_reset = 1;
......
......@@ -923,6 +923,22 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
struct scsi_device *sdev = q->queuedata;
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.
......@@ -945,6 +961,14 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
} else
cmd = req->special;
} 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
* it isn't, we refuse to process ordinary commands
......@@ -1127,6 +1151,10 @@ static void scsi_request_fn(struct request_queue *q)
struct scsi_cmnd *cmd;
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
* the host is no longer able to accept any more requests.
......@@ -1199,7 +1227,7 @@ static void scsi_request_fn(struct request_queue *q)
}
}
return;
goto out;
not_ready:
spin_unlock_irq(shost->host_lock);
......@@ -1217,6 +1245,12 @@ static void scsi_request_fn(struct request_queue *q)
sdev->device_busy--;
if(sdev->device_busy == 0)
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)
......
......@@ -130,7 +130,6 @@ extern void scsi_exit_procfs(void);
extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
unsigned int, unsigned int, int);
extern void scsi_forget_host(struct Scsi_Host *);
extern void scsi_free_sdev(struct scsi_device *);
extern void scsi_rescan_device(struct device *);
/* scsi_sysctl.c */
......@@ -143,7 +142,8 @@ extern void scsi_exit_sysctl(void);
#endif /* CONFIG_SYSCTL */
/* 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_register(void);
extern void scsi_sysfs_unregister(void);
......
......@@ -205,6 +205,7 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
sdev->lun = lun;
sdev->channel = channel;
sdev->online = TRUE;
sdev->sdev_state = SDEV_CREATED;
INIT_LIST_HEAD(&sdev->siblings);
INIT_LIST_HEAD(&sdev->same_target_siblings);
INIT_LIST_HEAD(&sdev->cmd_list);
......@@ -236,6 +237,25 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
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
* sibling list
......@@ -272,36 +292,6 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
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
* @sreq: used to send the INQUIRY
......@@ -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
* about it.
*/
scsi_device_register(sdev);
scsi_sysfs_add_sdev(sdev);
return SCSI_SCAN_LUN_PRESENT;
}
......@@ -748,8 +738,11 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
if (res == SCSI_SCAN_LUN_PRESENT) {
if (sdevp)
*sdevp = sdev;
} else
scsi_free_sdev(sdev);
} else {
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
put_device(&sdev->sdev_gendev);
}
out:
return res;
}
......@@ -1301,5 +1294,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
void scsi_free_host_dev(struct scsi_device *sdev)
{
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)
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 device *parent;
unsigned long flags;
parent = dev->parent;
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);
}
......@@ -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
* @sdev: scsi_device to register
* scsi_sysfs_add_sdev - add scsi device to sysfs
* @sdev: scsi_device to add
*
* Return value:
* 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;
set_bit(SDEV_ADD, &sdev->sdev_state);
device_initialize(&sdev->sdev_gendev);
sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
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);
int error = -EINVAL, i;
if (sdev->sdev_state != SDEV_CREATED)
return error;
sdev->sdev_state = SDEV_RUNNING;
error = device_add(&sdev->sdev_gendev);
if (error) {
......@@ -351,8 +357,6 @@ int scsi_device_register(struct scsi_device *sdev)
return error;
}
get_device(sdev->sdev_gendev.parent);
error = class_device_add(&sdev->sdev_classdev);
if (error) {
printk(KERN_INFO "error 2\n");
......@@ -384,8 +388,11 @@ int scsi_device_register(struct scsi_device *sdev)
return error;
clean_device:
sdev->sdev_state = SDEV_CANCEL;
device_del(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
return error;
}
......@@ -396,12 +403,14 @@ int scsi_device_register(struct scsi_device *sdev)
**/
void scsi_remove_device(struct scsi_device *sdev)
{
class_device_unregister(&sdev->sdev_classdev);
set_bit(SDEV_DEL, &sdev->sdev_state);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
device_del(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
if (sdev->sdev_state == SDEV_RUNNING || sdev->sdev_state == SDEV_CANCEL) {
sdev->sdev_state = SDEV_DEL;
class_device_unregister(&sdev->sdev_classdev);
device_del(&sdev->sdev_gendev);
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
put_device(&sdev->sdev_gendev);
}
}
int scsi_register_driver(struct device_driver *drv)
......
......@@ -70,8 +70,8 @@ struct fb_info fb_info;
struct fb_fix_screeninfo igafb_fix __initdata = {
.id = "IGA 1682",
.type = FB_TYPE_PACKED_PIXELS;
.mmio_len = 1000;
.type = FB_TYPE_PACKED_PIXELS,
.mmio_len = 1000
};
struct fb_var_screeninfo default_var = {
......@@ -149,7 +149,7 @@ struct fb_var_screeninfo default_var_1280x1024 __initdata = {
.xres = 1280,
.yres = 1024,
.xres_virtual = 1280,
.yres_virtaul = 1024,
.yres_virtual = 1024,
.bits_per_pixel = 8,
.red = {0, 8, 0 },
.green = {0, 8, 0 },
......@@ -300,17 +300,17 @@ static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (regno < 16) {
switch (info->var.bits_per_pixel) {
case 16:
info->pseudo_palette[regno] =
((u16*)(info->pseudo_palette))[regno] =
(regno << 10) | (regno << 5) | regno;
break;
case 24:
info->pseudo_palette[regno] =
((u32*)(info->pseudo_palette))[regno] =
(regno << 16) | (regno << 8) | regno;
break;
case 32:
{ int i;
i = (regno << 8) | regno;
info->pseudo_palette[regno] = (i << 16) | i;
((u32*)(info->pseudo_palette))[regno] = (i << 16) | i;
}
break;
}
......@@ -359,7 +359,7 @@ static int __init iga_init(struct fb_info *info, struct iga_par *par)
info->fbops = &igafb_ops;
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)
return 0;
......
......@@ -1415,8 +1415,8 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
int i;
struct tblock *target;
/* jfs_write_inode may call us during read-only mount */
if (!log)
/* jfs_write_inode may call us during read-only mount */
return;
jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait);
......
......@@ -198,6 +198,7 @@ void proc_tty_register_driver(struct tty_driver *driver)
return;
ent->read_proc = driver->read_proc;
ent->write_proc = driver->write_proc;
ent->owner = driver->owner;
ent->data = driver;
driver->proc_entry = ent;
......
......@@ -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. */
#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 */
......@@ -310,6 +310,7 @@ struct ata_port {
struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
u8 ctl; /* cache of ATA control register */
u8 last_ctl; /* Cache last written value */
unsigned int bus_state;
unsigned int port_state;
unsigned int pio_mask;
......@@ -522,12 +523,12 @@ static inline u8 ata_irq_on(struct ata_port *ap)
struct ata_ioports *ioaddr = &ap->ioaddr;
ap->ctl &= ~ATA_NIEN;
ap->last_ctl = ap->ctl;
if (ap->flags & ATA_FLAG_MMIO)
writeb(ap->ctl, ioaddr->ctl_addr);
else
outb(ap->ctl, ioaddr->ctl_addr);
return ata_wait_idle(ap);
}
......
......@@ -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)
{
int err = 0;
int skb_len;
/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
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)
skb->dev = NULL;
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);
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_data_ready(sk, skb->len);
sk->sk_data_ready(sk, skb_len);
out:
return err;
}
......
......@@ -14,11 +14,15 @@ struct scsi_mode_data;
/*
* sdev state
*/
enum {
SDEV_ADD,
SDEV_DEL,
SDEV_CANCEL,
SDEV_RECOVERY,
enum scsi_device_state {
SDEV_CREATED, /* device created but not added to sysfs
* Only internal commands allowed (for inq) */
SDEV_RUNNING, /* device properly configured
* All commands allowed */
SDEV_CANCEL, /* beginning to delete device
* Only error handler commands allowed */
SDEV_DEL, /* device deleted
* no commands allowed */
};
struct scsi_device {
......@@ -99,7 +103,7 @@ struct scsi_device {
struct device sdev_gendev;
struct class_device sdev_classdev;
unsigned long sdev_state;
enum scsi_device_state sdev_state;
};
#define to_scsi_device(d) \
container_of(d, struct scsi_device, sdev_gendev)
......
......@@ -1014,6 +1014,7 @@ struct task_struct *copy_process(unsigned long clone_flags,
if (current->signal->group_exit) {
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -EAGAIN;
goto bad_fork_cleanup_namespace;
}
p->tgid = current->tgid;
......
......@@ -32,7 +32,7 @@ int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
static int __init br_init(void)
{
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER)
#ifdef CONFIG_BRIDGE_NETFILTER
if (br_netfilter_init())
return 1;
#endif
......@@ -50,7 +50,7 @@ static int __init br_init(void)
static void __exit br_deinit(void)
{
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER)
#ifdef CONFIG_BRIDGE_NETFILTER
br_netfilter_fini();
#endif
unregister_netdevice_notifier(&br_device_notifier);
......
......@@ -1041,12 +1041,15 @@ static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
if (!sk)
goto drop;
return ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb,
hdr->port);
if (ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb,
hdr->port))
goto drop;
return 0;
drop:
kfree_skb(skb);
return 0;
return NET_RX_DROP;
}
static struct packet_type econet_packet_type = {
......
......@@ -1924,9 +1924,13 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_unlock_bh(&addrconf_hash_lock);
}
/* Step 3: clear address list */
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
if (how == 1 && del_timer(&idev->regen_timer))
in6_dev_put(idev);
......@@ -1962,7 +1966,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
}
write_unlock_bh(&idev->lock);
/* Step 4: Discard multicast list */
/* Step 5: Discard multicast list */
if (how == 1)
ipv6_mc_destroy_dev(idev);
......
......@@ -47,6 +47,9 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
#include <net/sock.h>
#include <net/snmp.h>
......@@ -1270,6 +1273,7 @@ static void mld_sendpack(struct sk_buff *skb)
struct mld2_report *pmr = (struct mld2_report *)skb->h.raw;
int payload_len, mldlen;
struct inet6_dev *idev = in6_dev_get(skb->dev);
int err;
payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
sizeof(struct ipv6hdr);
......@@ -1278,8 +1282,10 @@ static void mld_sendpack(struct sk_buff *skb)
pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
dev_queue_xmit(skb);
ICMP6_INC_STATS(idev,Icmp6OutMsgs);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit);
if (!err)
ICMP6_INC_STATS(idev,Icmp6OutMsgs);
if (likely(idev != NULL))
in6_dev_put(idev);
}
......@@ -1608,12 +1614,15 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
idev = in6_dev_get(skb->dev);
dev_queue_xmit(skb);
if (type == ICMPV6_MGM_REDUCTION)
ICMP6_INC_STATS(idev, Icmp6OutGroupMembReductions);
else
ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
ICMP6_INC_STATS(idev, Icmp6OutMsgs);
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit);
if (!err) {
if (type == ICMPV6_MGM_REDUCTION)
ICMP6_INC_STATS(idev, Icmp6OutGroupMembReductions);
else
ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
ICMP6_INC_STATS(idev, Icmp6OutMsgs);
}
if (likely(idev != NULL))
in6_dev_put(idev);
......
......@@ -859,10 +859,10 @@ static int irttp_udata_indication(void *instance, void *sap,
err = self->notify.udata_indication(self->notify.instance,
self,skb);
/* Same comment as in irttp_do_data_indication() */
if (err != -ENOMEM)
if (!err)
return 0;
}
/* Either no handler, or -ENOMEM */
/* Either no handler, or handler returns an error */
dev_kfree_skb(skb);
return 0;
......@@ -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
* give an error back
*/
if (err == -ENOMEM) {
if (err) {
IRDA_DEBUG(0, "%s() requeueing skb!\n", __FUNCTION__);
/* 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