From e4472cb3706ceea42797ae1dc79d624026986694 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 Jan 2006 15:53:55 -0800 Subject: [CPUFREQ] cpufreq_notify_transition cleanup. Introduce caching of cpufreq_cpu_data[freqs->cpu], which allows us to make the function a lot more readable, and as a nice side-effect, it now fits in < 80 column displays again. Signed-off-by: Dave Jones diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7a51147..6bbe582 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -229,44 +229,53 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { /** - * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition + * cpufreq_notify_transition - call notifier chain and adjust_jiffies + * on frequency transition. * - * This function calls the transition notifiers and the "adjust_jiffies" function. It is called - * twice on all CPU frequency changes that have external effects. + * This function calls the transition notifiers and the "adjust_jiffies" + * function. It is called twice on all CPU frequency changes that have + * external effects. */ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) { + struct cpufreq_policy *policy; + BUG_ON(irqs_disabled()); freqs->flags = cpufreq_driver->flags; - dprintk("notification %u of frequency transition to %u kHz\n", state, freqs->new); + dprintk("notification %u of frequency transition to %u kHz\n", + state, freqs->new); down_read(&cpufreq_notifier_rwsem); + + policy = cpufreq_cpu_data[freqs->cpu]; switch (state) { + case CPUFREQ_PRECHANGE: - /* detect if the driver reported a value as "old frequency" which - * is not equal to what the cpufreq core thinks is "old frequency". + /* detect if the driver reported a value as "old frequency" + * which is not equal to what the cpufreq core thinks is + * "old frequency". */ if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { - if ((likely(cpufreq_cpu_data[freqs->cpu])) && - (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)) && - (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && - (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) - { - dprintk(KERN_WARNING "Warning: CPU frequency is %u, " - "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur); - freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; + if ((policy) && (policy->cpu == freqs->cpu) && + (policy->cur) && (policy->cur != freqs->old)) { + dprintk(KERN_WARNING "Warning: CPU frequency is" + " %u, cpufreq assumed %u kHz.\n", + freqs->old, policy->cur); + freqs->old = policy->cur; } } - notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs); + notifier_call_chain(&cpufreq_transition_notifier_list, + CPUFREQ_PRECHANGE, freqs); adjust_jiffies(CPUFREQ_PRECHANGE, freqs); break; + case CPUFREQ_POSTCHANGE: adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); - notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs); - if ((likely(cpufreq_cpu_data[freqs->cpu])) && - (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu))) - cpufreq_cpu_data[freqs->cpu]->cur = freqs->new; + notifier_call_chain(&cpufreq_transition_notifier_list, + CPUFREQ_POSTCHANGE, freqs); + if (likely(policy) && likely(policy->cpu == freqs->cpu)) + policy->cur = freqs->new; break; } up_read(&cpufreq_notifier_rwsem); -- cgit v0.10.2 From 9d2725bb815d915fc6c8531097d9e71b579a8763 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Wed, 1 Feb 2006 11:38:37 +0100 Subject: [CPUFREQ] Check for not initialized freq on cpufreq changes Test for old_freq equals 0 to insure not to divide by 0: ______________________________________________ Check for not initialized freq on cpufreq changes Signed-off-by: Thomas Renninger Signed-off-by: Dave Jones diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 47675bb..591a642 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c @@ -272,6 +272,10 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, if (val != CPUFREQ_RESUMECHANGE) write_seqlock_irq(&xtime_lock); if (!ref_freq) { + if (!freq->old){ + ref_freq = freq->new; + goto end; + } ref_freq = freq->old; loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; #ifndef CONFIG_SMP @@ -297,6 +301,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, #endif } +end: if (val != CPUFREQ_RESUMECHANGE) write_sequnlock_irq(&xtime_lock); -- cgit v0.10.2 From a85f7bd310dbc9010309bfe70b6b02432a11ef59 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Wed, 1 Feb 2006 11:36:04 +0100 Subject: [CPUFREQ] Check whether driver init did not initialize current freq Check whether driver init did not initialize current freq Signed-off-by: Thomas Renninger Signed-off-by: Dave Jones diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 6bbe582..35eafbc 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1442,8 +1442,13 @@ int cpufreq_update_policy(unsigned int cpu) -> ask driver for current freq and notify governors about a change */ if (cpufreq_driver->get) { policy.cur = cpufreq_driver->get(cpu); - if (data->cur != policy.cur) - cpufreq_out_of_sync(cpu, data->cur, policy.cur); + if (!data->cur) { + dprintk("Driver did not initialize current freq"); + data->cur = policy.cur; + } else { + if (data->cur != policy.cur) + cpufreq_out_of_sync(cpu, data->cur, policy.cur); + } } ret = __cpufreq_set_policy(data, &policy); -- cgit v0.10.2 From 7d5e350fab47f1273bc8b52d5f133ed6e4baeb7f Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 2 Feb 2006 17:03:42 -0500 Subject: [CPUFREQ] Whitespace/CodingStyle cleanups Signed-off-by: Dave Jones diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 35eafbc..9582de1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -35,8 +35,8 @@ * level driver of CPUFreq support, and its spinlock. This lock * also protects the cpufreq_cpu_data array. */ -static struct cpufreq_driver *cpufreq_driver; -static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; +static struct cpufreq_driver *cpufreq_driver; +static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; static DEFINE_SPINLOCK(cpufreq_driver_lock); /* internal prototypes */ @@ -50,15 +50,15 @@ static void handle_update(void *data); * changes to devices when the CPU clock speed changes. * The mutex locks both lists. */ -static struct notifier_block *cpufreq_policy_notifier_list; -static struct notifier_block *cpufreq_transition_notifier_list; -static DECLARE_RWSEM (cpufreq_notifier_rwsem); +static struct notifier_block *cpufreq_policy_notifier_list; +static struct notifier_block *cpufreq_transition_notifier_list; +static DECLARE_RWSEM (cpufreq_notifier_rwsem); static LIST_HEAD(cpufreq_governor_list); -static DEFINE_MUTEX (cpufreq_governor_mutex); +static DEFINE_MUTEX (cpufreq_governor_mutex); -struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu) +struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) { struct cpufreq_policy *data; unsigned long flags; @@ -85,20 +85,19 @@ struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu) if (!kobject_get(&data->kobj)) goto err_out_put_module; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - return data; - err_out_put_module: +err_out_put_module: module_put(cpufreq_driver->owner); - err_out_unlock: +err_out_unlock: spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - err_out: +err_out: return NULL; } EXPORT_SYMBOL_GPL(cpufreq_cpu_get); + void cpufreq_cpu_put(struct cpufreq_policy *data) { kobject_put(&data->kobj); @@ -317,7 +316,7 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, return 0; } } - out: +out: mutex_unlock(&cpufreq_governor_mutex); } return -EINVAL; @@ -424,7 +423,6 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy, return -EINVAL; ret = cpufreq_set_policy(&new_policy); - return ret ? ret : count; } @@ -455,7 +453,7 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy, goto out; i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); } - out: +out: i += sprintf(&buf[i], "\n"); return i; } @@ -798,7 +796,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) kfree(data); cpufreq_debug_enable_ratelimit(); - return 0; } @@ -879,8 +876,7 @@ unsigned int cpufreq_get(unsigned int cpu) ret = cpufreq_driver->get(cpu); - if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) - { + if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { /* verify no discrepancy between actual and saved value exists */ if (unlikely(ret != policy->cur)) { cpufreq_out_of_sync(cpu, policy->cur, ret); @@ -890,7 +886,7 @@ unsigned int cpufreq_get(unsigned int cpu) mutex_unlock(&policy->lock); - out: +out: cpufreq_cpu_put(policy); return (ret); @@ -971,7 +967,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) cpu_policy->cur = cur_freq; } - out: +out: cpufreq_cpu_put(cpu_policy); return 0; } @@ -1178,7 +1174,6 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, mutex_unlock(&policy->lock); cpufreq_cpu_put(policy); - return ret; } EXPORT_SYMBOL_GPL(cpufreq_driver_target); @@ -1217,7 +1212,6 @@ int cpufreq_governor(unsigned int cpu, unsigned int event) mutex_unlock(&policy->lock); cpufreq_cpu_put(policy); - return ret; } EXPORT_SYMBOL_GPL(cpufreq_governor); @@ -1241,7 +1235,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor) list_add(&governor->governor_list, &cpufreq_governor_list); mutex_unlock(&cpufreq_governor_mutex); - return 0; } EXPORT_SYMBOL_GPL(cpufreq_register_governor); @@ -1286,7 +1279,6 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) mutex_unlock(&cpu_policy->lock); cpufreq_cpu_put(cpu_policy); - return 0; } EXPORT_SYMBOL(cpufreq_get_policy); @@ -1300,9 +1292,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, policy->min, policy->max); - memcpy(&policy->cpuinfo, - &data->cpuinfo, - sizeof(struct cpufreq_cpuinfo)); + memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo)); /* verify the cpu speed can be set within this limit */ ret = cpufreq_driver->verify(policy); @@ -1333,8 +1323,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli up_read(&cpufreq_notifier_rwsem); - data->min = policy->min; - data->max = policy->max; + data->min = policy->min; + data->max = policy->max; dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max); @@ -1371,7 +1361,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); } - error_out: +error_out: cpufreq_debug_enable_ratelimit(); return ret; } @@ -1430,9 +1420,7 @@ int cpufreq_update_policy(unsigned int cpu) mutex_lock(&data->lock); dprintk("updating policy for CPU %u\n", cpu); - memcpy(&policy, - data, - sizeof(struct cpufreq_policy)); + memcpy(&policy, data, sizeof(struct cpufreq_policy)); policy.min = data->user_policy.min; policy.max = data->user_policy.max; policy.policy = data->user_policy.policy; -- cgit v0.10.2 From 8cf3f04f45694db0699f608c0e3fb550c607cc88 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Fri, 3 Feb 2006 14:28:48 -0800 Subject: IB/mad: Handle DR SMPs with a LID routed part Fix handling of directed route SMPs with a beginning or ending LID routed part. Signed-off-by: Ralph Campbell Signed-off-by: Hal Rosenstock Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index d393b50..c82f47a 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -665,7 +665,15 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, struct ib_wc mad_wc; struct ib_send_wr *send_wr = &mad_send_wr->send_wr; - if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) { + /* + * Directed route handling starts if the initial LID routed part of + * a request or the ending LID routed part of a response is empty. + * If we are at the start of the LID routed part, don't update the + * hop_ptr or hop_cnt. See section 14.2.2, Vol 1 IB spec. + */ + if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) == + IB_LID_PERMISSIVE && + !smi_handle_dr_smp_send(smp, device->node_type, port_num)) { ret = -EINVAL; printk(KERN_ERR PFX "Invalid directed route\n"); goto out; -- cgit v0.10.2 From 04414013bbda644b65537e73f1dacb2821b36811 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 31 Jan 2006 16:04:51 -0800 Subject: [SCSI] qla2xxx: Add port-speed FC transport attribute. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index b17ee62..e03140f 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -426,6 +426,26 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost) } static void +qla2x00_get_host_speed(struct Scsi_Host *shost) +{ + scsi_qla_host_t *ha = to_qla_host(shost); + uint32_t speed = 0; + + switch (ha->link_data_rate) { + case LDR_1GB: + speed = 1; + break; + case LDR_2GB: + speed = 2; + break; + case LDR_4GB: + speed = 4; + break; + } + fc_host_speed(shost) = speed; +} + +static void qla2x00_get_starget_node_name(struct scsi_target *starget) { struct Scsi_Host *host = dev_to_shost(starget->dev.parent); @@ -520,6 +540,8 @@ struct fc_function_template qla2xxx_transport_functions = { .get_host_port_id = qla2x00_get_host_port_id, .show_host_port_id = 1, + .get_host_speed = qla2x00_get_host_speed, + .show_host_speed = 1, .dd_fcrport_size = sizeof(struct fc_port *), .show_rport_supported_classes = 1, diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index bad066e..26af531 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2331,6 +2331,10 @@ typedef struct scsi_qla_host { uint16_t min_external_loopid; /* First external loop Id */ uint16_t link_data_rate; /* F/W operating speed */ +#define LDR_1GB 0 +#define LDR_2GB 1 +#define LDR_4GB 3 +#define LDR_UNKNOWN 0xFFFF uint8_t current_topology; uint8_t prev_topology; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 71a46fc..42aa7a7 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -402,9 +402,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_LOOP_UP: /* Loop Up Event */ - ha->link_data_rate = 0; if (IS_QLA2100(ha) || IS_QLA2200(ha)) { link_speed = link_speeds[0]; + ha->link_data_rate = LDR_1GB; } else { link_speed = link_speeds[LS_UNKNOWN]; if (mb[1] < 5) @@ -436,7 +436,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) } ha->flags.management_server_logged_in = 0; - ha->link_data_rate = 0; + ha->link_data_rate = LDR_UNKNOWN; if (ql2xfdmienable) set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5866a7c..6e133ed 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1312,6 +1312,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->ports = MAX_BUSES; ha->init_cb_size = sizeof(init_cb_t); ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; + ha->link_data_rate = LDR_UNKNOWN; /* Assign ISP specific operations. */ ha->isp_ops.pci_config = qla2100_pci_config; -- cgit v0.10.2 From 8d067623adf119081b7a2683cdc6ee90eb8a70b2 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 31 Jan 2006 16:04:56 -0800 Subject: [SCSI] qla2xxx: Add host port-type FC transport attribute. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index e03140f..5501632 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -446,6 +446,29 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) } static void +qla2x00_get_host_port_type(struct Scsi_Host *shost) +{ + scsi_qla_host_t *ha = to_qla_host(shost); + uint32_t port_type = FC_PORTTYPE_UNKNOWN; + + switch (ha->current_topology) { + case ISP_CFG_NL: + port_type = FC_PORTTYPE_LPORT; + break; + case ISP_CFG_FL: + port_type = FC_PORTTYPE_NLPORT; + break; + case ISP_CFG_N: + port_type = FC_PORTTYPE_PTP; + break; + case ISP_CFG_F: + port_type = FC_PORTTYPE_NPORT; + break; + } + fc_host_port_type(shost) = port_type; +} + +static void qla2x00_get_starget_node_name(struct scsi_target *starget) { struct Scsi_Host *host = dev_to_shost(starget->dev.parent); @@ -542,6 +565,8 @@ struct fc_function_template qla2xxx_transport_functions = { .show_host_port_id = 1, .get_host_speed = qla2x00_get_host_speed, .show_host_speed = 1, + .get_host_port_type = qla2x00_get_host_port_type, + .show_host_port_type = 1, .dd_fcrport_size = sizeof(struct fc_port *), .show_rport_supported_classes = 1, -- cgit v0.10.2 From 392e2f651c8a83484116a407a9f121e534c22b5a Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 31 Jan 2006 16:05:02 -0800 Subject: [SCSI] qla2xxx: Add host-statistics FC transport attributes. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 5501632..5a8d5c4 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -7,7 +7,6 @@ #include "qla_def.h" #include -#include /* SYSFS attributes --------------------------------------------------------- */ @@ -555,6 +554,41 @@ qla2x00_issue_lip(struct Scsi_Host *shost) return 0; } +static struct fc_host_statistics * +qla2x00_get_fc_host_stats(struct Scsi_Host *shost) +{ + scsi_qla_host_t *ha = to_qla_host(shost); + int rval; + uint16_t mb_stat[1]; + link_stat_t stat_buf; + struct fc_host_statistics *pfc_host_stat; + + pfc_host_stat = &ha->fc_host_stat; + memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); + + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { + rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, + sizeof(stat_buf) / 4, mb_stat); + } else { + rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf, + mb_stat); + } + if (rval != 0) { + qla_printk(KERN_WARNING, ha, + "Unable to retrieve host statistics (%d).\n", mb_stat[0]); + return pfc_host_stat; + } + + pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt; + pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt; + pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt; + pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt; + pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt; + pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt; + + return pfc_host_stat; +} + struct fc_function_template qla2xxx_transport_functions = { .show_host_node_name = 1, @@ -583,6 +617,7 @@ struct fc_function_template qla2xxx_transport_functions = { .show_rport_dev_loss_tmo = 1, .issue_fc_host_lip = qla2x00_issue_lip, + .get_fc_host_stats = qla2x00_get_fc_host_stats, }; void diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 26af531..4145808 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -29,6 +29,7 @@ #include #include #include +#include #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE) @@ -2496,6 +2497,7 @@ typedef struct scsi_qla_host { uint16_t zio_mode; uint16_t zio_timer; + struct fc_host_statistics fc_host_stat; } scsi_qla_host_t; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 35266bd..f2f5454 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -185,6 +185,13 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *, extern int qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); +extern int +qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, link_stat_t *, + uint16_t *); + +extern int +qla24xx_get_isp_stats(scsi_qla_host_t *, uint32_t *, uint32_t, uint16_t *); + extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); extern int qla24xx_abort_target(fc_port_t *); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e67bb09..634ee17 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -8,7 +8,6 @@ #include #include -#include #include "qla_devtbl.h" diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 3099b37..49ce197 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -7,7 +7,6 @@ #include "qla_def.h" #include -#include static void qla2x00_mbx_sem_timeout(unsigned long data) @@ -2017,8 +2016,109 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map) return rval; } +#endif + +/* + * qla2x00_get_link_status + * + * Input: + * ha = adapter block pointer. + * loop_id = device loop ID. + * ret_buf = pointer to link status return buffer. + * + * Returns: + * 0 = success. + * BIT_0 = mem alloc error. + * BIT_1 = mailbox error. + */ +int +qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, + link_stat_t *ret_buf, uint16_t *status) +{ + int rval; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + link_stat_t *stat_buf; + dma_addr_t stat_buf_dma; + + DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) + + stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); + if (stat_buf == NULL) { + DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", + __func__, ha->host_no)); + return BIT_0; + } + memset(stat_buf, 0, sizeof(link_stat_t)); + + mcp->mb[0] = MBC_GET_LINK_STATUS; + mcp->mb[2] = MSW(stat_buf_dma); + mcp->mb[3] = LSW(stat_buf_dma); + mcp->mb[6] = MSW(MSD(stat_buf_dma)); + mcp->mb[7] = LSW(MSD(stat_buf_dma)); + mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; + mcp->in_mb = MBX_0; + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { + mcp->mb[1] = loop_id; + mcp->mb[4] = 0; + mcp->mb[10] = 0; + mcp->out_mb |= MBX_10|MBX_4|MBX_1; + mcp->in_mb |= MBX_1; + } else if (HAS_EXTENDED_IDS(ha)) { + mcp->mb[1] = loop_id; + mcp->mb[10] = 0; + mcp->out_mb |= MBX_10|MBX_1; + } else { + mcp->mb[1] = loop_id << 8; + mcp->out_mb |= MBX_1; + } + mcp->tov = 30; + mcp->flags = IOCTL_CMD; + rval = qla2x00_mailbox_command(ha, mcp); + + if (rval == QLA_SUCCESS) { + if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { + DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", + __func__, ha->host_no, mcp->mb[0]);) + status[0] = mcp->mb[0]; + rval = BIT_1; + } else { + /* copy over data -- firmware data is LE. */ + ret_buf->link_fail_cnt = + le32_to_cpu(stat_buf->link_fail_cnt); + ret_buf->loss_sync_cnt = + le32_to_cpu(stat_buf->loss_sync_cnt); + ret_buf->loss_sig_cnt = + le32_to_cpu(stat_buf->loss_sig_cnt); + ret_buf->prim_seq_err_cnt = + le32_to_cpu(stat_buf->prim_seq_err_cnt); + ret_buf->inval_xmit_word_cnt = + le32_to_cpu(stat_buf->inval_xmit_word_cnt); + ret_buf->inval_crc_cnt = + le32_to_cpu(stat_buf->inval_crc_cnt); + + DEBUG11(printk("%s(%ld): stat dump: fail_cnt=%d " + "loss_sync=%d loss_sig=%d seq_err=%d " + "inval_xmt_word=%d inval_crc=%d.\n", __func__, + ha->host_no, stat_buf->link_fail_cnt, + stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, + stat_buf->prim_seq_err_cnt, + stat_buf->inval_xmit_word_cnt, + stat_buf->inval_crc_cnt);) + } + } else { + /* Failed. */ + DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, + ha->host_no, rval);) + rval = BIT_1; + } + + dma_pool_free(ha->s_dma_pool, stat_buf, stat_buf_dma); -uint8_t + return rval; +} + +int qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, uint16_t *status) { @@ -2080,7 +2180,6 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, return rval; } -#endif int qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c index 2c33421..b70bebe 100644 --- a/drivers/scsi/qla2xxx/qla_rscn.c +++ b/drivers/scsi/qla2xxx/qla_rscn.c @@ -6,8 +6,6 @@ */ #include "qla_def.h" -#include - /** * IO descriptor handle definitions. * -- cgit v0.10.2 From f6df144cca19cc60dda6dcce65d236b70cc46494 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 31 Jan 2006 16:05:07 -0800 Subject: [SCSI] qla2xxx: Add beacon support via class-device attribute. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 5a8d5c4..049e5cf 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -196,6 +196,9 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); + + if (ha->beacon_blink_led == 1) + ha->isp_ops.beacon_off(ha); } /* Scsi_Host attributes. */ @@ -383,6 +386,50 @@ qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, return strlen(buf); } +static ssize_t +qla2x00_beacon_show(struct class_device *cdev, char *buf) +{ + scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + int len = 0; + + if (ha->beacon_blink_led) + len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n"); + else + len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); + return len; +} + +static ssize_t +qla2x00_beacon_store(struct class_device *cdev, const char *buf, + size_t count) +{ + scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + int val = 0; + int rval; + + if (IS_QLA2100(ha) || IS_QLA2200(ha)) + return -EPERM; + + if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) { + qla_printk(KERN_WARNING, ha, + "Abort ISP active -- ignoring beacon request.\n"); + return -EBUSY; + } + + if (sscanf(buf, "%d", &val) != 1) + return -EINVAL; + + if (val) + rval = ha->isp_ops.beacon_on(ha); + else + rval = ha->isp_ops.beacon_off(ha); + + if (rval != QLA_SUCCESS) + count = 0; + + return count; +} + static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); @@ -397,6 +444,8 @@ static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show, qla2x00_zio_store); static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show, qla2x00_zio_timer_store); +static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show, + qla2x00_beacon_store); struct class_device_attribute *qla2x00_host_attrs[] = { &class_device_attr_driver_version, @@ -410,6 +459,7 @@ struct class_device_attribute *qla2x00_host_attrs[] = { &class_device_attr_state, &class_device_attr_zio, &class_device_attr_zio_timer, + &class_device_attr_beacon, NULL, }; diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 4145808..7cb8b5a 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -182,6 +182,13 @@ #define WRT_REG_DWORD(addr, data) writel(data,addr) /* + * The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an + * 133Mhz slot. + */ +#define RD_REG_WORD_PIO(addr) (inw((unsigned long)addr)) +#define WRT_REG_WORD_PIO(addr, data) (outw(data,(unsigned long)addr)) + +/* * Fibre Channel device definitions. */ #define WWN_SIZE 8 /* Size of WWPN, WWN & WWNN */ @@ -433,6 +440,9 @@ struct device_reg_2xxx { #define GPIO_LED_GREEN_ON_AMBER_OFF 0x0040 #define GPIO_LED_GREEN_OFF_AMBER_ON 0x0080 #define GPIO_LED_GREEN_ON_AMBER_ON 0x00C0 +#define GPIO_LED_ALL_OFF 0x0000 +#define GPIO_LED_RED_ON_OTHER_OFF 0x0001 /* isp2322 */ +#define GPIO_LED_RGA_ON 0x00C1 /* isp2322: red green amber */ union { struct { @@ -2200,6 +2210,10 @@ struct isp_operations { void (*fw_dump) (struct scsi_qla_host *, int); void (*ascii_fw_dump) (struct scsi_qla_host *); + + int (*beacon_on) (struct scsi_qla_host *); + int (*beacon_off) (struct scsi_qla_host *); + void (*beacon_blink) (struct scsi_qla_host *); }; /* @@ -2493,7 +2507,12 @@ typedef struct scsi_qla_host { /* Needed for BEACON */ uint16_t beacon_blink_led; - uint16_t beacon_green_on; + uint8_t beacon_color_state; +#define QLA_LED_GRN_ON 0x01 +#define QLA_LED_YLW_ON 0x02 +#define QLA_LED_ABR_ON 0x04 +#define QLA_LED_ALL_ON 0x07 /* yellow, green, amber. */ + /* ISP2322: red, green, amber. */ uint16_t zio_mode; uint16_t zio_timer; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f2f5454..eb35198 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -75,8 +75,6 @@ extern void qla2x00_cmd_timeout(srb_t *); extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); -extern void qla2x00_blink_led(scsi_qla_host_t *); - extern int qla2x00_down_timeout(struct semaphore *, unsigned long); extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); @@ -235,6 +233,13 @@ extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, uint32_t); +extern int qla2x00_beacon_on(struct scsi_qla_host *); +extern int qla2x00_beacon_off(struct scsi_qla_host *); +extern void qla2x00_beacon_blink(struct scsi_qla_host *); +extern int qla24xx_beacon_on(struct scsi_qla_host *); +extern int qla24xx_beacon_off(struct scsi_qla_host *); +extern void qla24xx_beacon_blink(struct scsi_qla_host *); + /* * Global Function Prototypes in qla_dbg.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 6e133ed..57179da 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1365,6 +1365,9 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->isp_ops.intr_handler = qla2300_intr_handler; ha->isp_ops.fw_dump = qla2300_fw_dump; ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; + ha->isp_ops.beacon_on = qla2x00_beacon_on; + ha->isp_ops.beacon_off = qla2x00_beacon_off; + ha->isp_ops.beacon_blink = qla2x00_beacon_blink; ha->gid_list_info_size = 6; } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { host->max_id = MAX_TARGETS_2200; @@ -1401,6 +1404,9 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->isp_ops.write_nvram = qla24xx_write_nvram_data; ha->isp_ops.fw_dump = qla24xx_fw_dump; ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; + ha->isp_ops.beacon_on = qla24xx_beacon_on; + ha->isp_ops.beacon_off = qla24xx_beacon_off; + ha->isp_ops.beacon_blink = qla24xx_beacon_blink; ha->gid_list_info_size = 8; } host->can_queue = ha->request_q_length + 128; @@ -2315,6 +2321,9 @@ qla2x00_do_dpc(void *data) if (!ha->interrupts_on) ha->isp_ops.enable_intrs(ha); + if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags)) + ha->isp_ops.beacon_blink(ha); + ha->dpc_active = 0; } /* End of while(1) */ @@ -2492,6 +2501,12 @@ qla2x00_timer(scsi_qla_host_t *ha) atomic_read(&ha->loop_down_timer))); } + /* Check if beacon LED needs to be blinked */ + if (ha->beacon_blink_led == 1) { + set_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags); + start_dpc++; + } + /* Schedule the DPC routine if needed */ if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || @@ -2500,6 +2515,7 @@ qla2x00_timer(scsi_qla_host_t *ha) start_dpc || test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || + test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && ha->dpc_wait && !ha->dpc_active) { diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index f4d755a..3105bb9 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -695,3 +695,297 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, return ret; } + + +static inline void +qla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags) +{ + if (IS_QLA2322(ha)) { + /* Flip all colors. */ + if (ha->beacon_color_state == QLA_LED_ALL_ON) { + /* Turn off. */ + ha->beacon_color_state = 0; + *pflags = GPIO_LED_ALL_OFF; + } else { + /* Turn on. */ + ha->beacon_color_state = QLA_LED_ALL_ON; + *pflags = GPIO_LED_RGA_ON; + } + } else { + /* Flip green led only. */ + if (ha->beacon_color_state == QLA_LED_GRN_ON) { + /* Turn off. */ + ha->beacon_color_state = 0; + *pflags = GPIO_LED_GREEN_OFF_AMBER_OFF; + } else { + /* Turn on. */ + ha->beacon_color_state = QLA_LED_GRN_ON; + *pflags = GPIO_LED_GREEN_ON_AMBER_OFF; + } + } +} + +void +qla2x00_beacon_blink(struct scsi_qla_host *ha) +{ + uint16_t gpio_enable; + uint16_t gpio_data; + uint16_t led_color = 0; + unsigned long flags; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + if (ha->pio_address) + reg = (struct device_reg_2xxx __iomem *)ha->pio_address; + + spin_lock_irqsave(&ha->hardware_lock, flags); + + /* Save the Original GPIOE. */ + if (ha->pio_address) { + gpio_enable = RD_REG_WORD_PIO(®->gpioe); + gpio_data = RD_REG_WORD_PIO(®->gpiod); + } else { + gpio_enable = RD_REG_WORD(®->gpioe); + gpio_data = RD_REG_WORD(®->gpiod); + } + + /* Set the modified gpio_enable values */ + gpio_enable |= GPIO_LED_MASK; + + if (ha->pio_address) { + WRT_REG_WORD_PIO(®->gpioe, gpio_enable); + } else { + WRT_REG_WORD(®->gpioe, gpio_enable); + RD_REG_WORD(®->gpioe); + } + + qla2x00_flip_colors(ha, &led_color); + + /* Clear out any previously set LED color. */ + gpio_data &= ~GPIO_LED_MASK; + + /* Set the new input LED color to GPIOD. */ + gpio_data |= led_color; + + /* Set the modified gpio_data values */ + if (ha->pio_address) { + WRT_REG_WORD_PIO(®->gpiod, gpio_data); + } else { + WRT_REG_WORD(®->gpiod, gpio_data); + RD_REG_WORD(®->gpiod); + } + + spin_unlock_irqrestore(&ha->hardware_lock, flags); +} + +int +qla2x00_beacon_on(struct scsi_qla_host *ha) +{ + uint16_t gpio_enable; + uint16_t gpio_data; + unsigned long flags; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; + ha->fw_options[1] |= FO1_DISABLE_GPIO6_7; + + if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) { + qla_printk(KERN_WARNING, ha, + "Unable to update fw options (beacon on).\n"); + return QLA_FUNCTION_FAILED; + } + + if (ha->pio_address) + reg = (struct device_reg_2xxx __iomem *)ha->pio_address; + + /* Turn off LEDs. */ + spin_lock_irqsave(&ha->hardware_lock, flags); + if (ha->pio_address) { + gpio_enable = RD_REG_WORD_PIO(®->gpioe); + gpio_data = RD_REG_WORD_PIO(®->gpiod); + } else { + gpio_enable = RD_REG_WORD(®->gpioe); + gpio_data = RD_REG_WORD(®->gpiod); + } + gpio_enable |= GPIO_LED_MASK; + + /* Set the modified gpio_enable values. */ + if (ha->pio_address) { + WRT_REG_WORD_PIO(®->gpioe, gpio_enable); + } else { + WRT_REG_WORD(®->gpioe, gpio_enable); + RD_REG_WORD(®->gpioe); + } + + /* Clear out previously set LED colour. */ + gpio_data &= ~GPIO_LED_MASK; + if (ha->pio_address) { + WRT_REG_WORD_PIO(®->gpiod, gpio_data); + } else { + WRT_REG_WORD(®->gpiod, gpio_data); + RD_REG_WORD(®->gpiod); + } + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + /* + * Let the per HBA timer kick off the blinking process based on + * the following flags. No need to do anything else now. + */ + ha->beacon_blink_led = 1; + ha->beacon_color_state = 0; + + return QLA_SUCCESS; +} + +int +qla2x00_beacon_off(struct scsi_qla_host *ha) +{ + int rval = QLA_SUCCESS; + + ha->beacon_blink_led = 0; + + /* Set the on flag so when it gets flipped it will be off. */ + if (IS_QLA2322(ha)) + ha->beacon_color_state = QLA_LED_ALL_ON; + else + ha->beacon_color_state = QLA_LED_GRN_ON; + + ha->isp_ops.beacon_blink(ha); /* This turns green LED off */ + + ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; + ha->fw_options[1] &= ~FO1_DISABLE_GPIO6_7; + + rval = qla2x00_set_fw_options(ha, ha->fw_options); + if (rval != QLA_SUCCESS) + qla_printk(KERN_WARNING, ha, + "Unable to update fw options (beacon off).\n"); + return rval; +} + + +static inline void +qla24xx_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags) +{ + /* Flip all colors. */ + if (ha->beacon_color_state == QLA_LED_ALL_ON) { + /* Turn off. */ + ha->beacon_color_state = 0; + *pflags = 0; + } else { + /* Turn on. */ + ha->beacon_color_state = QLA_LED_ALL_ON; + *pflags = GPDX_LED_YELLOW_ON | GPDX_LED_AMBER_ON; + } +} + +void +qla24xx_beacon_blink(struct scsi_qla_host *ha) +{ + uint16_t led_color = 0; + uint32_t gpio_data; + unsigned long flags; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + + /* Save the Original GPIOD. */ + spin_lock_irqsave(&ha->hardware_lock, flags); + gpio_data = RD_REG_DWORD(®->gpiod); + + /* Enable the gpio_data reg for update. */ + gpio_data |= GPDX_LED_UPDATE_MASK; + + WRT_REG_DWORD(®->gpiod, gpio_data); + gpio_data = RD_REG_DWORD(®->gpiod); + + /* Set the color bits. */ + qla24xx_flip_colors(ha, &led_color); + + /* Clear out any previously set LED color. */ + gpio_data &= ~GPDX_LED_COLOR_MASK; + + /* Set the new input LED color to GPIOD. */ + gpio_data |= led_color; + + /* Set the modified gpio_data values. */ + WRT_REG_DWORD(®->gpiod, gpio_data); + gpio_data = RD_REG_DWORD(®->gpiod); + spin_unlock_irqrestore(&ha->hardware_lock, flags); +} + +int +qla24xx_beacon_on(struct scsi_qla_host *ha) +{ + uint32_t gpio_data; + unsigned long flags; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + + if (ha->beacon_blink_led == 0) { + /* Enable firmware for update */ + ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL; + + if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) + return QLA_FUNCTION_FAILED; + + if (qla2x00_get_fw_options(ha, ha->fw_options) != + QLA_SUCCESS) { + qla_printk(KERN_WARNING, ha, + "Unable to update fw options (beacon on).\n"); + return QLA_FUNCTION_FAILED; + } + + spin_lock_irqsave(&ha->hardware_lock, flags); + gpio_data = RD_REG_DWORD(®->gpiod); + + /* Enable the gpio_data reg for update. */ + gpio_data |= GPDX_LED_UPDATE_MASK; + WRT_REG_DWORD(®->gpiod, gpio_data); + RD_REG_DWORD(®->gpiod); + + spin_unlock_irqrestore(&ha->hardware_lock, flags); + } + + /* So all colors blink together. */ + ha->beacon_color_state = 0; + + /* Let the per HBA timer kick off the blinking process. */ + ha->beacon_blink_led = 1; + + return QLA_SUCCESS; +} + +int +qla24xx_beacon_off(struct scsi_qla_host *ha) +{ + uint32_t gpio_data; + unsigned long flags; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + + ha->beacon_blink_led = 0; + ha->beacon_color_state = QLA_LED_ALL_ON; + + ha->isp_ops.beacon_blink(ha); /* Will flip to all off. */ + + /* Give control back to firmware. */ + spin_lock_irqsave(&ha->hardware_lock, flags); + gpio_data = RD_REG_DWORD(®->gpiod); + + /* Disable the gpio_data reg for update. */ + gpio_data &= ~GPDX_LED_UPDATE_MASK; + WRT_REG_DWORD(®->gpiod, gpio_data); + RD_REG_DWORD(®->gpiod); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + ha->fw_options[1] &= ~ADD_FO1_DISABLE_GPIO_LED_CTRL; + + if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) { + qla_printk(KERN_WARNING, ha, + "Unable to update fw options (beacon off).\n"); + return QLA_FUNCTION_FAILED; + } + + if (qla2x00_get_fw_options(ha, ha->fw_options) != QLA_SUCCESS) { + qla_printk(KERN_WARNING, ha, + "Unable to get fw options (beacon off).\n"); + return QLA_FUNCTION_FAILED; + } + + return QLA_SUCCESS; +} -- cgit v0.10.2 From 1b3f63659bd353ae460c35f5793a9fd46cc95014 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 31 Jan 2006 16:05:12 -0800 Subject: [SCSI] qla2xxx: Return correct data-len during NVRAM retrieval. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 049e5cf..73d10b3 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -113,7 +113,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off, struct device, kobj))); unsigned long flags; - if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) + if (!capable(CAP_SYS_ADMIN) || off != 0) return 0; /* Read NVRAM. */ @@ -122,7 +122,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off, ha->nvram_size); spin_unlock_irqrestore(&ha->hardware_lock, flags); - return (count); + return ha->nvram_size; } static ssize_t @@ -174,7 +174,7 @@ static struct bin_attribute sysfs_nvram_attr = { .mode = S_IRUSR | S_IWUSR, .owner = THIS_MODULE, }, - .size = 0, + .size = 512, .read = qla2x00_sysfs_read_nvram, .write = qla2x00_sysfs_write_nvram, }; @@ -185,7 +185,6 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) struct Scsi_Host *host = ha->host; sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); - sysfs_nvram_attr.size = ha->nvram_size; sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); } -- cgit v0.10.2 From 854165f4245c4a3b4a8cc363ba2050033151e196 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 31 Jan 2006 16:05:17 -0800 Subject: [SCSI] qla2xxx: Add support to retrieve/update HBA option-rom. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 73d10b3..92b3e13 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -179,6 +179,135 @@ static struct bin_attribute sysfs_nvram_attr = { .write = qla2x00_sysfs_write_nvram, }; +static ssize_t +qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off, + size_t count) +{ + struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct device, kobj))); + + if (ha->optrom_state != QLA_SREADING) + return 0; + if (off > ha->optrom_size) + return 0; + if (off + count > ha->optrom_size) + count = ha->optrom_size - off; + + memcpy(buf, &ha->optrom_buffer[off], count); + + return count; +} + +static ssize_t +qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off, + size_t count) +{ + struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct device, kobj))); + + if (ha->optrom_state != QLA_SWRITING) + return -EINVAL; + if (off > ha->optrom_size) + return -ERANGE; + if (off + count > ha->optrom_size) + count = ha->optrom_size - off; + + memcpy(&ha->optrom_buffer[off], buf, count); + + return count; +} + +static struct bin_attribute sysfs_optrom_attr = { + .attr = { + .name = "optrom", + .mode = S_IRUSR | S_IWUSR, + .owner = THIS_MODULE, + }, + .size = OPTROM_SIZE_24XX, + .read = qla2x00_sysfs_read_optrom, + .write = qla2x00_sysfs_write_optrom, +}; + +static ssize_t +qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off, + size_t count) +{ + struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct device, kobj))); + int val; + + if (off) + return 0; + + if (sscanf(buf, "%d", &val) != 1) + return -EINVAL; + + switch (val) { + case 0: + if (ha->optrom_state != QLA_SREADING && + ha->optrom_state != QLA_SWRITING) + break; + + ha->optrom_state = QLA_SWAITING; + vfree(ha->optrom_buffer); + ha->optrom_buffer = NULL; + break; + case 1: + if (ha->optrom_state != QLA_SWAITING) + break; + + ha->optrom_state = QLA_SREADING; + ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); + if (ha->optrom_buffer == NULL) { + qla_printk(KERN_WARNING, ha, + "Unable to allocate memory for optrom retrieval " + "(%x).\n", ha->optrom_size); + + ha->optrom_state = QLA_SWAITING; + return count; + } + + memset(ha->optrom_buffer, 0, ha->optrom_size); + ha->isp_ops.read_optrom(ha, ha->optrom_buffer, 0, + ha->optrom_size); + break; + case 2: + if (ha->optrom_state != QLA_SWAITING) + break; + + ha->optrom_state = QLA_SWRITING; + ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); + if (ha->optrom_buffer == NULL) { + qla_printk(KERN_WARNING, ha, + "Unable to allocate memory for optrom update " + "(%x).\n", ha->optrom_size); + + ha->optrom_state = QLA_SWAITING; + return count; + } + memset(ha->optrom_buffer, 0, ha->optrom_size); + break; + case 3: + if (ha->optrom_state != QLA_SWRITING) + break; + + ha->isp_ops.write_optrom(ha, ha->optrom_buffer, 0, + ha->optrom_size); + break; + } + return count; +} + +static struct bin_attribute sysfs_optrom_ctl_attr = { + .attr = { + .name = "optrom_ctl", + .mode = S_IWUSR, + .owner = THIS_MODULE, + }, + .size = 0, + .write = qla2x00_sysfs_write_optrom_ctl, +}; + void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) { @@ -186,6 +315,9 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); + sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); + sysfs_create_bin_file(&host->shost_gendev.kobj, + &sysfs_optrom_ctl_attr); } void @@ -195,6 +327,9 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); + sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); + sysfs_remove_bin_file(&host->shost_gendev.kobj, + &sysfs_optrom_ctl_attr); if (ha->beacon_blink_led == 1) ha->isp_ops.beacon_off(ha); diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7cb8b5a..b31a03b 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2214,6 +2214,11 @@ struct isp_operations { int (*beacon_on) (struct scsi_qla_host *); int (*beacon_off) (struct scsi_qla_host *); void (*beacon_blink) (struct scsi_qla_host *); + + uint8_t * (*read_optrom) (struct scsi_qla_host *, uint8_t *, + uint32_t, uint32_t); + int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t, + uint32_t); }; /* @@ -2505,6 +2510,14 @@ typedef struct scsi_qla_host { uint8_t *port_name; uint32_t isp_abort_cnt; + /* Option ROM information. */ + char *optrom_buffer; + uint32_t optrom_size; + int optrom_state; +#define QLA_SWAITING 0 +#define QLA_SREADING 1 +#define QLA_SWRITING 2 + /* Needed for BEACON */ uint16_t beacon_blink_led; uint8_t beacon_color_state; @@ -2582,7 +2595,9 @@ struct _qla2x00stats { /* * Flash support definitions */ -#define FLASH_IMAGE_SIZE 131072 +#define OPTROM_SIZE_2300 0x20000 +#define OPTROM_SIZE_2322 0x100000 +#define OPTROM_SIZE_24XX 0x100000 #include "qla_gbl.h" #include "qla_dbg.h" diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index eb35198..ffdc268 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -79,6 +79,8 @@ extern int qla2x00_down_timeout(struct semaphore *, unsigned long); extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); +extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *); + /* * Global Function Prototypes in qla_iocb.c source file. */ @@ -240,6 +242,15 @@ extern int qla24xx_beacon_on(struct scsi_qla_host *); extern int qla24xx_beacon_off(struct scsi_qla_host *); extern void qla24xx_beacon_blink(struct scsi_qla_host *); +extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *, + uint32_t, uint32_t); +extern int qla2x00_write_optrom_data(struct scsi_qla_host *, uint8_t *, + uint32_t, uint32_t); +extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, + uint32_t, uint32_t); +extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, + uint32_t, uint32_t); + /* * Global Function Prototypes in qla_dbg.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 57179da..495ccbc 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -513,7 +513,7 @@ qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) * Success (Adapter is online) : 0 * Failed (Adapter is offline/disabled) : 1 */ -static int +int qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) { int return_status; @@ -1271,6 +1271,9 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) fc_port_t *fcport; struct scsi_host_template *sht; +if (PCI_FUNC(pdev->devfn)) + goto probe_out; + if (pci_enable_device(pdev)) goto probe_out; @@ -1313,6 +1316,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->init_cb_size = sizeof(init_cb_t); ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; ha->link_data_rate = LDR_UNKNOWN; + ha->optrom_size = OPTROM_SIZE_2300; /* Assign ISP specific operations. */ ha->isp_ops.pci_config = qla2100_pci_config; @@ -1340,6 +1344,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->isp_ops.write_nvram = qla2x00_write_nvram_data; ha->isp_ops.fw_dump = qla2100_fw_dump; ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump; + ha->isp_ops.read_optrom = qla2x00_read_optrom_data; + ha->isp_ops.write_optrom = qla2x00_write_optrom_data; if (IS_QLA2100(ha)) { host->max_id = MAX_TARGETS_2100; ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; @@ -1369,6 +1375,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->isp_ops.beacon_off = qla2x00_beacon_off; ha->isp_ops.beacon_blink = qla2x00_beacon_blink; ha->gid_list_info_size = 6; + if (IS_QLA2322(ha) || IS_QLA6322(ha)) + ha->optrom_size = OPTROM_SIZE_2322; } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { host->max_id = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; @@ -1404,10 +1412,13 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->isp_ops.write_nvram = qla24xx_write_nvram_data; ha->isp_ops.fw_dump = qla24xx_fw_dump; ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; + ha->isp_ops.read_optrom = qla24xx_read_optrom_data; + ha->isp_ops.write_optrom = qla24xx_write_optrom_data; ha->isp_ops.beacon_on = qla24xx_beacon_on; ha->isp_ops.beacon_off = qla24xx_beacon_off; ha->isp_ops.beacon_blink = qla24xx_beacon_blink; ha->gid_list_info_size = 8; + ha->optrom_size = OPTROM_SIZE_24XX; } host->can_queue = ha->request_q_length + 128; @@ -2073,6 +2084,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha) ha->fw_dumped = 0; ha->fw_dump_reading = 0; ha->fw_dump_buffer = NULL; + + vfree(ha->optrom_buffer); } /* diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 3105bb9..3866a57 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -989,3 +989,672 @@ qla24xx_beacon_off(struct scsi_qla_host *ha) return QLA_SUCCESS; } + + +/* + * Flash support routines + */ + +/** + * qla2x00_flash_enable() - Setup flash for reading and writing. + * @ha: HA context + */ +static void +qla2x00_flash_enable(scsi_qla_host_t *ha) +{ + uint16_t data; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + data = RD_REG_WORD(®->ctrl_status); + data |= CSR_FLASH_ENABLE; + WRT_REG_WORD(®->ctrl_status, data); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ +} + +/** + * qla2x00_flash_disable() - Disable flash and allow RISC to run. + * @ha: HA context + */ +static void +qla2x00_flash_disable(scsi_qla_host_t *ha) +{ + uint16_t data; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + data = RD_REG_WORD(®->ctrl_status); + data &= ~(CSR_FLASH_ENABLE); + WRT_REG_WORD(®->ctrl_status, data); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ +} + +/** + * qla2x00_read_flash_byte() - Reads a byte from flash + * @ha: HA context + * @addr: Address in flash to read + * + * A word is read from the chip, but, only the lower byte is valid. + * + * Returns the byte read from flash @addr. + */ +static uint8_t +qla2x00_read_flash_byte(scsi_qla_host_t *ha, uint32_t addr) +{ + uint16_t data; + uint16_t bank_select; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + bank_select = RD_REG_WORD(®->ctrl_status); + + if (IS_QLA2322(ha) || IS_QLA6322(ha)) { + /* Specify 64K address range: */ + /* clear out Module Select and Flash Address bits [19:16]. */ + bank_select &= ~0xf8; + bank_select |= addr >> 12 & 0xf0; + bank_select |= CSR_FLASH_64K_BANK; + WRT_REG_WORD(®->ctrl_status, bank_select); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + + WRT_REG_WORD(®->flash_address, (uint16_t)addr); + data = RD_REG_WORD(®->flash_data); + + return (uint8_t)data; + } + + /* Setup bit 16 of flash address. */ + if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) { + bank_select |= CSR_FLASH_64K_BANK; + WRT_REG_WORD(®->ctrl_status, bank_select); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + } else if (((addr & BIT_16) == 0) && + (bank_select & CSR_FLASH_64K_BANK)) { + bank_select &= ~(CSR_FLASH_64K_BANK); + WRT_REG_WORD(®->ctrl_status, bank_select); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + } + + /* Always perform IO mapped accesses to the FLASH registers. */ + if (ha->pio_address) { + uint16_t data2; + + reg = (struct device_reg_2xxx __iomem *)ha->pio_address; + WRT_REG_WORD_PIO(®->flash_address, (uint16_t)addr); + do { + data = RD_REG_WORD_PIO(®->flash_data); + barrier(); + cpu_relax(); + data2 = RD_REG_WORD_PIO(®->flash_data); + } while (data != data2); + } else { + WRT_REG_WORD(®->flash_address, (uint16_t)addr); + data = qla2x00_debounce_register(®->flash_data); + } + + return (uint8_t)data; +} + +/** + * qla2x00_write_flash_byte() - Write a byte to flash + * @ha: HA context + * @addr: Address in flash to write + * @data: Data to write + */ +static void +qla2x00_write_flash_byte(scsi_qla_host_t *ha, uint32_t addr, uint8_t data) +{ + uint16_t bank_select; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + bank_select = RD_REG_WORD(®->ctrl_status); + if (IS_QLA2322(ha) || IS_QLA6322(ha)) { + /* Specify 64K address range: */ + /* clear out Module Select and Flash Address bits [19:16]. */ + bank_select &= ~0xf8; + bank_select |= addr >> 12 & 0xf0; + bank_select |= CSR_FLASH_64K_BANK; + WRT_REG_WORD(®->ctrl_status, bank_select); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + + WRT_REG_WORD(®->flash_address, (uint16_t)addr); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + WRT_REG_WORD(®->flash_data, (uint16_t)data); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + + return; + } + + /* Setup bit 16 of flash address. */ + if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) { + bank_select |= CSR_FLASH_64K_BANK; + WRT_REG_WORD(®->ctrl_status, bank_select); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + } else if (((addr & BIT_16) == 0) && + (bank_select & CSR_FLASH_64K_BANK)) { + bank_select &= ~(CSR_FLASH_64K_BANK); + WRT_REG_WORD(®->ctrl_status, bank_select); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + } + + /* Always perform IO mapped accesses to the FLASH registers. */ + if (ha->pio_address) { + reg = (struct device_reg_2xxx __iomem *)ha->pio_address; + WRT_REG_WORD_PIO(®->flash_address, (uint16_t)addr); + WRT_REG_WORD_PIO(®->flash_data, (uint16_t)data); + } else { + WRT_REG_WORD(®->flash_address, (uint16_t)addr); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + WRT_REG_WORD(®->flash_data, (uint16_t)data); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ + } +} + +/** + * qla2x00_poll_flash() - Polls flash for completion. + * @ha: HA context + * @addr: Address in flash to poll + * @poll_data: Data to be polled + * @man_id: Flash manufacturer ID + * @flash_id: Flash ID + * + * This function polls the device until bit 7 of what is read matches data + * bit 7 or until data bit 5 becomes a 1. If that hapens, the flash ROM timed + * out (a fatal error). The flash book recommeds reading bit 7 again after + * reading bit 5 as a 1. + * + * Returns 0 on success, else non-zero. + */ +static int +qla2x00_poll_flash(scsi_qla_host_t *ha, uint32_t addr, uint8_t poll_data, + uint8_t man_id, uint8_t flash_id) +{ + int status; + uint8_t flash_data; + uint32_t cnt; + + status = 1; + + /* Wait for 30 seconds for command to finish. */ + poll_data &= BIT_7; + for (cnt = 3000000; cnt; cnt--) { + flash_data = qla2x00_read_flash_byte(ha, addr); + if ((flash_data & BIT_7) == poll_data) { + status = 0; + break; + } + + if (man_id != 0x40 && man_id != 0xda) { + if ((flash_data & BIT_5) && cnt > 2) + cnt = 2; + } + udelay(10); + barrier(); + } + return status; +} + +#define IS_OEM_001(ha) \ + ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322 && \ + (ha)->pdev->subsystem_vendor == 0x1028 && \ + (ha)->pdev->subsystem_device == 0x0170) + +/** + * qla2x00_program_flash_address() - Programs a flash address + * @ha: HA context + * @addr: Address in flash to program + * @data: Data to be written in flash + * @man_id: Flash manufacturer ID + * @flash_id: Flash ID + * + * Returns 0 on success, else non-zero. + */ +static int +qla2x00_program_flash_address(scsi_qla_host_t *ha, uint32_t addr, uint8_t data, + uint8_t man_id, uint8_t flash_id) +{ + /* Write Program Command Sequence. */ + if (IS_OEM_001(ha)) { + qla2x00_write_flash_byte(ha, 0xaaa, 0xaa); + qla2x00_write_flash_byte(ha, 0x555, 0x55); + qla2x00_write_flash_byte(ha, 0xaaa, 0xa0); + qla2x00_write_flash_byte(ha, addr, data); + } else { + if (man_id == 0xda && flash_id == 0xc1) { + qla2x00_write_flash_byte(ha, addr, data); + if (addr & 0x7e) + return 0; + } else { + qla2x00_write_flash_byte(ha, 0x5555, 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); + qla2x00_write_flash_byte(ha, 0x5555, 0xa0); + qla2x00_write_flash_byte(ha, addr, data); + } + } + + udelay(150); + + /* Wait for write to complete. */ + return qla2x00_poll_flash(ha, addr, data, man_id, flash_id); +} + +/** + * qla2x00_erase_flash() - Erase the flash. + * @ha: HA context + * @man_id: Flash manufacturer ID + * @flash_id: Flash ID + * + * Returns 0 on success, else non-zero. + */ +static int +qla2x00_erase_flash(scsi_qla_host_t *ha, uint8_t man_id, uint8_t flash_id) +{ + /* Individual Sector Erase Command Sequence */ + if (IS_OEM_001(ha)) { + qla2x00_write_flash_byte(ha, 0xaaa, 0xaa); + qla2x00_write_flash_byte(ha, 0x555, 0x55); + qla2x00_write_flash_byte(ha, 0xaaa, 0x80); + qla2x00_write_flash_byte(ha, 0xaaa, 0xaa); + qla2x00_write_flash_byte(ha, 0x555, 0x55); + qla2x00_write_flash_byte(ha, 0xaaa, 0x10); + } else { + qla2x00_write_flash_byte(ha, 0x5555, 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); + qla2x00_write_flash_byte(ha, 0x5555, 0x80); + qla2x00_write_flash_byte(ha, 0x5555, 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); + qla2x00_write_flash_byte(ha, 0x5555, 0x10); + } + + udelay(150); + + /* Wait for erase to complete. */ + return qla2x00_poll_flash(ha, 0x00, 0x80, man_id, flash_id); +} + +/** + * qla2x00_erase_flash_sector() - Erase a flash sector. + * @ha: HA context + * @addr: Flash sector to erase + * @sec_mask: Sector address mask + * @man_id: Flash manufacturer ID + * @flash_id: Flash ID + * + * Returns 0 on success, else non-zero. + */ +static int +qla2x00_erase_flash_sector(scsi_qla_host_t *ha, uint32_t addr, + uint32_t sec_mask, uint8_t man_id, uint8_t flash_id) +{ + /* Individual Sector Erase Command Sequence */ + qla2x00_write_flash_byte(ha, 0x5555, 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); + qla2x00_write_flash_byte(ha, 0x5555, 0x80); + qla2x00_write_flash_byte(ha, 0x5555, 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); + if (man_id == 0x1f && flash_id == 0x13) + qla2x00_write_flash_byte(ha, addr & sec_mask, 0x10); + else + qla2x00_write_flash_byte(ha, addr & sec_mask, 0x30); + + udelay(150); + + /* Wait for erase to complete. */ + return qla2x00_poll_flash(ha, addr, 0x80, man_id, flash_id); +} + +/** + * qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip. + * @man_id: Flash manufacturer ID + * @flash_id: Flash ID + */ +static void +qla2x00_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, + uint8_t *flash_id) +{ + qla2x00_write_flash_byte(ha, 0x5555, 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); + qla2x00_write_flash_byte(ha, 0x5555, 0x90); + *man_id = qla2x00_read_flash_byte(ha, 0x0000); + *flash_id = qla2x00_read_flash_byte(ha, 0x0001); + qla2x00_write_flash_byte(ha, 0x5555, 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); + qla2x00_write_flash_byte(ha, 0x5555, 0xf0); +} + + +static inline void +qla2x00_suspend_hba(struct scsi_qla_host *ha) +{ + int cnt; + unsigned long flags; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + /* Suspend HBA. */ + scsi_block_requests(ha->host); + ha->isp_ops.disable_intrs(ha); + set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); + + /* Pause RISC. */ + spin_lock_irqsave(&ha->hardware_lock, flags); + WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); + RD_REG_WORD(®->hccr); + if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) { + for (cnt = 0; cnt < 30000; cnt++) { + if ((RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) != 0) + break; + udelay(100); + } + } else { + udelay(10); + } + spin_unlock_irqrestore(&ha->hardware_lock, flags); +} + +static inline void +qla2x00_resume_hba(struct scsi_qla_host *ha) +{ + /* Resume HBA. */ + clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); + set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); + up(ha->dpc_wait); + qla2x00_wait_for_hba_online(ha); + scsi_unblock_requests(ha->host); +} + +uint8_t * +qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, + uint32_t offset, uint32_t length) +{ + unsigned long flags; + uint32_t addr, midpoint; + uint8_t *data; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + /* Suspend HBA. */ + qla2x00_suspend_hba(ha); + + /* Go with read. */ + spin_lock_irqsave(&ha->hardware_lock, flags); + midpoint = ha->optrom_size / 2; + + qla2x00_flash_enable(ha); + WRT_REG_WORD(®->nvram, 0); + RD_REG_WORD(®->nvram); /* PCI Posting. */ + for (addr = offset, data = buf; addr < length; addr++, data++) { + if (addr == midpoint) { + WRT_REG_WORD(®->nvram, NVR_SELECT); + RD_REG_WORD(®->nvram); /* PCI Posting. */ + } + + *data = qla2x00_read_flash_byte(ha, addr); + } + qla2x00_flash_disable(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + /* Resume HBA. */ + qla2x00_resume_hba(ha); + + return buf; +} + +int +qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, + uint32_t offset, uint32_t length) +{ + + int rval; + unsigned long flags; + uint8_t man_id, flash_id, sec_number, data; + uint16_t wd; + uint32_t addr, liter, sec_mask, rest_addr; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + + /* Suspend HBA. */ + qla2x00_suspend_hba(ha); + + rval = QLA_SUCCESS; + sec_number = 0; + + /* Reset ISP chip. */ + spin_lock_irqsave(&ha->hardware_lock, flags); + WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); + pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); + + /* Go with write. */ + qla2x00_flash_enable(ha); + do { /* Loop once to provide quick error exit */ + /* Structure of flash memory based on manufacturer */ + if (IS_OEM_001(ha)) { + /* OEM variant with special flash part. */ + man_id = flash_id = 0; + rest_addr = 0xffff; + sec_mask = 0x10000; + goto update_flash; + } + qla2x00_get_flash_manufacturer(ha, &man_id, &flash_id); + switch (man_id) { + case 0x20: /* ST flash. */ + if (flash_id == 0xd2 || flash_id == 0xe3) { + /* + * ST m29w008at part - 64kb sector size with + * 32kb,8kb,8kb,16kb sectors at memory address + * 0xf0000. + */ + rest_addr = 0xffff; + sec_mask = 0x10000; + break; + } + /* + * ST m29w010b part - 16kb sector size + * Default to 16kb sectors + */ + rest_addr = 0x3fff; + sec_mask = 0x1c000; + break; + case 0x40: /* Mostel flash. */ + /* Mostel v29c51001 part - 512 byte sector size. */ + rest_addr = 0x1ff; + sec_mask = 0x1fe00; + break; + case 0xbf: /* SST flash. */ + /* SST39sf10 part - 4kb sector size. */ + rest_addr = 0xfff; + sec_mask = 0x1f000; + break; + case 0xda: /* Winbond flash. */ + /* Winbond W29EE011 part - 256 byte sector size. */ + rest_addr = 0x7f; + sec_mask = 0x1ff80; + break; + case 0xc2: /* Macronix flash. */ + /* 64k sector size. */ + if (flash_id == 0x38 || flash_id == 0x4f) { + rest_addr = 0xffff; + sec_mask = 0x10000; + break; + } + /* Fall through... */ + + case 0x1f: /* Atmel flash. */ + /* 512k sector size. */ + if (flash_id == 0x13) { + rest_addr = 0x7fffffff; + sec_mask = 0x80000000; + break; + } + /* Fall through... */ + + case 0x01: /* AMD flash. */ + if (flash_id == 0x38 || flash_id == 0x40 || + flash_id == 0x4f) { + /* Am29LV081 part - 64kb sector size. */ + /* Am29LV002BT part - 64kb sector size. */ + rest_addr = 0xffff; + sec_mask = 0x10000; + break; + } else if (flash_id == 0x3e) { + /* + * Am29LV008b part - 64kb sector size with + * 32kb,8kb,8kb,16kb sector at memory address + * h0xf0000. + */ + rest_addr = 0xffff; + sec_mask = 0x10000; + break; + } else if (flash_id == 0x20 || flash_id == 0x6e) { + /* + * Am29LV010 part or AM29f010 - 16kb sector + * size. + */ + rest_addr = 0x3fff; + sec_mask = 0x1c000; + break; + } else if (flash_id == 0x6d) { + /* Am29LV001 part - 8kb sector size. */ + rest_addr = 0x1fff; + sec_mask = 0x1e000; + break; + } + default: + /* Default to 16 kb sector size. */ + rest_addr = 0x3fff; + sec_mask = 0x1c000; + break; + } + +update_flash: + if (IS_QLA2322(ha) || IS_QLA6322(ha)) { + if (qla2x00_erase_flash(ha, man_id, flash_id)) { + rval = QLA_FUNCTION_FAILED; + break; + } + } + + for (addr = offset, liter = 0; liter < length; liter++, + addr++) { + data = buf[liter]; + /* Are we at the beginning of a sector? */ + if ((addr & rest_addr) == 0) { + if (IS_QLA2322(ha) || IS_QLA6322(ha)) { + if (addr >= 0x10000UL) { + if (((addr >> 12) & 0xf0) && + ((man_id == 0x01 && + flash_id == 0x3e) || + (man_id == 0x20 && + flash_id == 0xd2))) { + sec_number++; + if (sec_number == 1) { + rest_addr = + 0x7fff; + sec_mask = + 0x18000; + } else if ( + sec_number == 2 || + sec_number == 3) { + rest_addr = + 0x1fff; + sec_mask = + 0x1e000; + } else if ( + sec_number == 4) { + rest_addr = + 0x3fff; + sec_mask = + 0x1c000; + } + } + } + } else if (addr == ha->optrom_size / 2) { + WRT_REG_WORD(®->nvram, NVR_SELECT); + RD_REG_WORD(®->nvram); + } + + if (flash_id == 0xda && man_id == 0xc1) { + qla2x00_write_flash_byte(ha, 0x5555, + 0xaa); + qla2x00_write_flash_byte(ha, 0x2aaa, + 0x55); + qla2x00_write_flash_byte(ha, 0x5555, + 0xa0); + } else if (!IS_QLA2322(ha) && !IS_QLA6322(ha)) { + /* Then erase it */ + if (qla2x00_erase_flash_sector(ha, + addr, sec_mask, man_id, + flash_id)) { + rval = QLA_FUNCTION_FAILED; + break; + } + if (man_id == 0x01 && flash_id == 0x6d) + sec_number++; + } + } + + if (man_id == 0x01 && flash_id == 0x6d) { + if (sec_number == 1 && + addr == (rest_addr - 1)) { + rest_addr = 0x0fff; + sec_mask = 0x1f000; + } else if (sec_number == 3 && (addr & 0x7ffe)) { + rest_addr = 0x3fff; + sec_mask = 0x1c000; + } + } + + if (qla2x00_program_flash_address(ha, addr, data, + man_id, flash_id)) { + rval = QLA_FUNCTION_FAILED; + break; + } + } + } while (0); + qla2x00_flash_disable(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + /* Resume HBA. */ + qla2x00_resume_hba(ha); + + return rval; +} + +uint8_t * +qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, + uint32_t offset, uint32_t length) +{ + /* Suspend HBA. */ + scsi_block_requests(ha->host); + ha->isp_ops.disable_intrs(ha); + set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); + + /* Go with read. */ + qla24xx_read_flash_data(ha, (uint32_t *)buf, offset >> 2, length >> 2); + + /* Resume HBA. */ + clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); + ha->isp_ops.enable_intrs(ha); + scsi_unblock_requests(ha->host); + + return buf; +} + +int +qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, + uint32_t offset, uint32_t length) +{ + int rval; + + /* Suspend HBA. */ + scsi_block_requests(ha->host); + ha->isp_ops.disable_intrs(ha); + set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); + + /* Go with write. */ + rval = qla24xx_write_flash_data(ha, (uint32_t *)buf, offset >> 2, + length >> 2); + + /* Resume HBA -- RISC reset needed. */ + clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); + set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); + up(ha->dpc_wait); + qla2x00_wait_for_hba_online(ha); + scsi_unblock_requests(ha->host); + + return rval; +} -- cgit v0.10.2 From d8a571135aad527e5984c8094b7977c6914f2550 Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Wed, 1 Feb 2006 09:30:31 -0800 Subject: [SCSI] aacraid: reduce device probe warnings Received from Mark Salyzyn. This patch sets up some device quirks surrounding arrays to inform the scsi layer that various mode pages are not supported. This reduces the severity of the complaints that show up in the logs as the array devices are enumerated. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 0bf5f9a..45fc171 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -386,6 +386,10 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, static int aac_slave_configure(struct scsi_device *sdev) { struct Scsi_Host *host = sdev->host; + if (sdev_channel(sdev) == CONTAINER_CHANNEL) { + sdev->skip_ms_page_8 = 1; + sdev->skip_ms_page_3f = 1; + } if (sdev->tagged_supported) scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); -- cgit v0.10.2 From bfb35aa85057da4336af56a7f26e08031f4e3468 Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Wed, 1 Feb 2006 09:30:55 -0800 Subject: [SCSI] aacraid: Update global function names Received from Mark Salyzyn, Reduce the possibility of namespace collision. Prefix with aac_. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 7139659..b0f314e 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -173,10 +173,10 @@ int aac_get_config_status(struct aac_dev *dev) int status = 0; struct fib * fibptr; - if (!(fibptr = fib_alloc(dev))) + if (!(fibptr = aac_fib_alloc(dev))) return -ENOMEM; - fib_init(fibptr); + aac_fib_init(fibptr); { struct aac_get_config_status *dinfo; dinfo = (struct aac_get_config_status *) fib_data(fibptr); @@ -186,7 +186,7 @@ int aac_get_config_status(struct aac_dev *dev) dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data)); } - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, fibptr, sizeof (struct aac_get_config_status), FsaNormal, @@ -209,30 +209,30 @@ int aac_get_config_status(struct aac_dev *dev) status = -EINVAL; } } - fib_complete(fibptr); + aac_fib_complete(fibptr); /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ if (status >= 0) { if (commit == 1) { struct aac_commit_config * dinfo; - fib_init(fibptr); + aac_fib_init(fibptr); dinfo = (struct aac_commit_config *) fib_data(fibptr); dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG); - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, fibptr, sizeof (struct aac_commit_config), FsaNormal, 1, 1, NULL, NULL); - fib_complete(fibptr); + aac_fib_complete(fibptr); } else if (commit == 0) { printk(KERN_WARNING "aac_get_config_status: Foreign device configurations are being ignored\n"); } } - fib_free(fibptr); + aac_fib_free(fibptr); return status; } @@ -255,15 +255,15 @@ int aac_get_containers(struct aac_dev *dev) instance = dev->scsi_host_ptr->unique_id; - if (!(fibptr = fib_alloc(dev))) + if (!(fibptr = aac_fib_alloc(dev))) return -ENOMEM; - fib_init(fibptr); + aac_fib_init(fibptr); dinfo = (struct aac_get_container_count *) fib_data(fibptr); dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->type = cpu_to_le32(CT_GET_CONTAINER_COUNT); - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, fibptr, sizeof (struct aac_get_container_count), FsaNormal, @@ -272,7 +272,7 @@ int aac_get_containers(struct aac_dev *dev) if (status >= 0) { dresp = (struct aac_get_container_count_resp *)fib_data(fibptr); maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); - fib_complete(fibptr); + aac_fib_complete(fibptr); } if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) @@ -280,7 +280,7 @@ int aac_get_containers(struct aac_dev *dev) fsa_dev_ptr = (struct fsa_dev_info *) kmalloc( sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); if (!fsa_dev_ptr) { - fib_free(fibptr); + aac_fib_free(fibptr); return -ENOMEM; } memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); @@ -294,14 +294,14 @@ int aac_get_containers(struct aac_dev *dev) fsa_dev_ptr[index].devname[0] = '\0'; - fib_init(fibptr); + aac_fib_init(fibptr); dinfo = (struct aac_query_mount *) fib_data(fibptr); dinfo->command = cpu_to_le32(VM_NameServe); dinfo->count = cpu_to_le32(index); dinfo->type = cpu_to_le32(FT_FILESYS); - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, fibptr, sizeof (struct aac_query_mount), FsaNormal, @@ -319,7 +319,7 @@ int aac_get_containers(struct aac_dev *dev) dinfo->count = cpu_to_le32(index); dinfo->type = cpu_to_le32(FT_FILESYS); - if (fib_send(ContainerCommand, + if (aac_fib_send(ContainerCommand, fibptr, sizeof(struct aac_query_mount), FsaNormal, @@ -347,7 +347,7 @@ int aac_get_containers(struct aac_dev *dev) if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) fsa_dev_ptr[index].ro = 1; } - fib_complete(fibptr); + aac_fib_complete(fibptr); /* * If there are no more containers, then stop asking. */ @@ -355,7 +355,7 @@ int aac_get_containers(struct aac_dev *dev) break; } } - fib_free(fibptr); + aac_fib_free(fibptr); return status; } @@ -413,8 +413,8 @@ static void get_container_name_callback(void *context, struct fib * fibptr) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; - fib_complete(fibptr); - fib_free(fibptr); + aac_fib_complete(fibptr); + aac_fib_free(fibptr); scsicmd->scsi_done(scsicmd); } @@ -430,10 +430,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) dev = (struct aac_dev *)scsicmd->device->host->hostdata; - if (!(cmd_fibcontext = fib_alloc(dev))) + if (!(cmd_fibcontext = aac_fib_alloc(dev))) return -ENOMEM; - fib_init(cmd_fibcontext); + aac_fib_init(cmd_fibcontext); dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext); dinfo->command = cpu_to_le32(VM_ContainerConfig); @@ -441,7 +441,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) dinfo->cid = cpu_to_le32(cid); dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, cmd_fibcontext, sizeof (struct aac_get_name), FsaNormal, @@ -455,14 +455,14 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) if (status == -EINPROGRESS) return 0; - printk(KERN_WARNING "aac_get_container_name: fib_send failed with status: %d.\n", status); - fib_complete(cmd_fibcontext); - fib_free(cmd_fibcontext); + printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); + aac_fib_complete(cmd_fibcontext); + aac_fib_free(cmd_fibcontext); return -1; } /** - * probe_container - query a logical volume + * aac_probe_container - query a logical volume * @dev: device to query * @cid: container identifier * @@ -470,7 +470,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) * is updated in the struct fsa_dev_info structure rather than returned. */ -int probe_container(struct aac_dev *dev, int cid) +int aac_probe_container(struct aac_dev *dev, int cid) { struct fsa_dev_info *fsa_dev_ptr; int status; @@ -482,10 +482,10 @@ int probe_container(struct aac_dev *dev, int cid) fsa_dev_ptr = dev->fsa_dev; instance = dev->scsi_host_ptr->unique_id; - if (!(fibptr = fib_alloc(dev))) + if (!(fibptr = aac_fib_alloc(dev))) return -ENOMEM; - fib_init(fibptr); + aac_fib_init(fibptr); dinfo = (struct aac_query_mount *)fib_data(fibptr); @@ -493,14 +493,14 @@ int probe_container(struct aac_dev *dev, int cid) dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, fibptr, sizeof(struct aac_query_mount), FsaNormal, 1, 1, NULL, NULL); if (status < 0) { - printk(KERN_WARNING "aacraid: probe_container query failed.\n"); + printk(KERN_WARNING "aacraid: aac_probe_container query failed.\n"); goto error; } @@ -512,7 +512,7 @@ int probe_container(struct aac_dev *dev, int cid) dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); - if (fib_send(ContainerCommand, + if (aac_fib_send(ContainerCommand, fibptr, sizeof(struct aac_query_mount), FsaNormal, @@ -535,8 +535,8 @@ int probe_container(struct aac_dev *dev, int cid) } error: - fib_complete(fibptr); - fib_free(fibptr); + aac_fib_complete(fibptr); + aac_fib_free(fibptr); return status; } @@ -700,14 +700,14 @@ int aac_get_adapter_info(struct aac_dev* dev) struct aac_bus_info *command; struct aac_bus_info_response *bus_info; - if (!(fibptr = fib_alloc(dev))) + if (!(fibptr = aac_fib_alloc(dev))) return -ENOMEM; - fib_init(fibptr); + aac_fib_init(fibptr); info = (struct aac_adapter_info *) fib_data(fibptr); memset(info,0,sizeof(*info)); - rcode = fib_send(RequestAdapterInfo, + rcode = aac_fib_send(RequestAdapterInfo, fibptr, sizeof(*info), FsaNormal, @@ -716,8 +716,8 @@ int aac_get_adapter_info(struct aac_dev* dev) NULL); if (rcode < 0) { - fib_complete(fibptr); - fib_free(fibptr); + aac_fib_complete(fibptr); + aac_fib_free(fibptr); return rcode; } memcpy(&dev->adapter_info, info, sizeof(*info)); @@ -725,13 +725,13 @@ int aac_get_adapter_info(struct aac_dev* dev) if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) { struct aac_supplement_adapter_info * info; - fib_init(fibptr); + aac_fib_init(fibptr); info = (struct aac_supplement_adapter_info *) fib_data(fibptr); memset(info,0,sizeof(*info)); - rcode = fib_send(RequestSupplementAdapterInfo, + rcode = aac_fib_send(RequestSupplementAdapterInfo, fibptr, sizeof(*info), FsaNormal, @@ -748,7 +748,7 @@ int aac_get_adapter_info(struct aac_dev* dev) * GetBusInfo */ - fib_init(fibptr); + aac_fib_init(fibptr); bus_info = (struct aac_bus_info_response *) fib_data(fibptr); @@ -761,7 +761,7 @@ int aac_get_adapter_info(struct aac_dev* dev) command->MethodId = cpu_to_le32(1); command->CtlCmd = cpu_to_le32(GetBusInfo); - rcode = fib_send(ContainerCommand, + rcode = aac_fib_send(ContainerCommand, fibptr, sizeof (*bus_info), FsaNormal, @@ -891,8 +891,8 @@ int aac_get_adapter_info(struct aac_dev* dev) } } - fib_complete(fibptr); - fib_free(fibptr); + aac_fib_complete(fibptr); + aac_fib_free(fibptr); return rcode; } @@ -976,8 +976,8 @@ static void io_callback(void *context, struct fib * fibptr) ? sizeof(scsicmd->sense_buffer) : sizeof(dev->fsa_dev[cid].sense_data)); } - fib_complete(fibptr); - fib_free(fibptr); + aac_fib_complete(fibptr); + aac_fib_free(fibptr); scsicmd->scsi_done(scsicmd); } @@ -1062,11 +1062,11 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) /* * Alocate and initialize a Fib */ - if (!(cmd_fibcontext = fib_alloc(dev))) { + if (!(cmd_fibcontext = aac_fib_alloc(dev))) { return -1; } - fib_init(cmd_fibcontext); + aac_fib_init(cmd_fibcontext); if (dev->raw_io_interface) { struct aac_raw_io *readcmd; @@ -1086,7 +1086,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) /* * Now send the Fib to the adapter */ - status = fib_send(ContainerRawIo, + status = aac_fib_send(ContainerRawIo, cmd_fibcontext, fibsize, FsaNormal, @@ -1112,7 +1112,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) /* * Now send the Fib to the adapter */ - status = fib_send(ContainerCommand64, + status = aac_fib_send(ContainerCommand64, cmd_fibcontext, fibsize, FsaNormal, @@ -1136,7 +1136,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) /* * Now send the Fib to the adapter */ - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, cmd_fibcontext, fibsize, FsaNormal, @@ -1153,14 +1153,14 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) if (status == -EINPROGRESS) return 0; - printk(KERN_WARNING "aac_read: fib_send failed with status: %d.\n", status); + printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status); /* * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; scsicmd->scsi_done(scsicmd); - fib_complete(cmd_fibcontext); - fib_free(cmd_fibcontext); + aac_fib_complete(cmd_fibcontext); + aac_fib_free(cmd_fibcontext); return 0; } @@ -1228,12 +1228,12 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) /* * Allocate and initialize a Fib then setup a BlockWrite command */ - if (!(cmd_fibcontext = fib_alloc(dev))) { + if (!(cmd_fibcontext = aac_fib_alloc(dev))) { scsicmd->result = DID_ERROR << 16; scsicmd->scsi_done(scsicmd); return 0; } - fib_init(cmd_fibcontext); + aac_fib_init(cmd_fibcontext); if (dev->raw_io_interface) { struct aac_raw_io *writecmd; @@ -1253,7 +1253,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) /* * Now send the Fib to the adapter */ - status = fib_send(ContainerRawIo, + status = aac_fib_send(ContainerRawIo, cmd_fibcontext, fibsize, FsaNormal, @@ -1279,7 +1279,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) /* * Now send the Fib to the adapter */ - status = fib_send(ContainerCommand64, + status = aac_fib_send(ContainerCommand64, cmd_fibcontext, fibsize, FsaNormal, @@ -1305,7 +1305,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) /* * Now send the Fib to the adapter */ - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, cmd_fibcontext, fibsize, FsaNormal, @@ -1322,15 +1322,15 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) return 0; } - printk(KERN_WARNING "aac_write: fib_send failed with status: %d\n", status); + printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status); /* * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; scsicmd->scsi_done(scsicmd); - fib_complete(cmd_fibcontext); - fib_free(cmd_fibcontext); + aac_fib_complete(cmd_fibcontext); + aac_fib_free(cmd_fibcontext); return 0; } @@ -1369,8 +1369,8 @@ static void synchronize_callback(void *context, struct fib *fibptr) sizeof(cmd->sense_buffer))); } - fib_complete(fibptr); - fib_free(fibptr); + aac_fib_complete(fibptr); + aac_fib_free(fibptr); cmd->scsi_done(cmd); } @@ -1407,10 +1407,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) * Allocate and initialize a Fib */ if (!(cmd_fibcontext = - fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) + aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) return SCSI_MLQUEUE_HOST_BUSY; - fib_init(cmd_fibcontext); + aac_fib_init(cmd_fibcontext); synchronizecmd = fib_data(cmd_fibcontext); synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); @@ -1422,7 +1422,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) /* * Now send the Fib to the adapter */ - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, cmd_fibcontext, sizeof(struct aac_synchronize), FsaNormal, @@ -1437,9 +1437,9 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) return 0; printk(KERN_WARNING - "aac_synchronize: fib_send failed with status: %d.\n", status); - fib_complete(cmd_fibcontext); - fib_free(cmd_fibcontext); + "aac_synchronize: aac_fib_send failed with status: %d.\n", status); + aac_fib_complete(cmd_fibcontext); + aac_fib_free(cmd_fibcontext); return SCSI_MLQUEUE_HOST_BUSY; } @@ -1488,7 +1488,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) case READ_CAPACITY: case TEST_UNIT_READY: spin_unlock_irq(host->host_lock); - probe_container(dev, cid); + aac_probe_container(dev, cid); if ((fsa_dev_ptr[cid].valid & 1) == 0) fsa_dev_ptr[cid].valid = 0; spin_lock_irq(host->host_lock); @@ -2089,8 +2089,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr) */ scsicmd->result |= le32_to_cpu(srbreply->scsi_status); - fib_complete(fibptr); - fib_free(fibptr); + aac_fib_complete(fibptr); + aac_fib_free(fibptr); scsicmd->scsi_done(scsicmd); } @@ -2142,10 +2142,10 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) /* * Allocate and initialize a Fib then setup a BlockWrite command */ - if (!(cmd_fibcontext = fib_alloc(dev))) { + if (!(cmd_fibcontext = aac_fib_alloc(dev))) { return -1; } - fib_init(cmd_fibcontext); + aac_fib_init(cmd_fibcontext); srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext); srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); @@ -2179,7 +2179,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) /* * Now send the Fib to the adapter */ - status = fib_send(ScsiPortCommand64, cmd_fibcontext, + status = aac_fib_send(ScsiPortCommand64, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) aac_srb_callback, (void *) scsicmd); @@ -2201,7 +2201,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) /* * Now send the Fib to the adapter */ - status = fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, + status = aac_fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) aac_srb_callback, (void *) scsicmd); } /* @@ -2211,9 +2211,9 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) return 0; } - printk(KERN_WARNING "aac_srb: fib_send failed with status: %d\n", status); - fib_complete(cmd_fibcontext); - fib_free(cmd_fibcontext); + printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status); + aac_fib_complete(cmd_fibcontext); + aac_fib_free(cmd_fibcontext); return -1; } diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 66dbb6d..2d430b7 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1774,16 +1774,16 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor) struct scsi_cmnd; const char *aac_driverinfo(struct Scsi_Host *); -struct fib *fib_alloc(struct aac_dev *dev); -int fib_setup(struct aac_dev *dev); -void fib_map_free(struct aac_dev *dev); -void fib_free(struct fib * context); -void fib_init(struct fib * context); +struct fib *aac_fib_alloc(struct aac_dev *dev); +int aac_fib_setup(struct aac_dev *dev); +void aac_fib_map_free(struct aac_dev *dev); +void aac_fib_free(struct fib * context); +void aac_fib_init(struct fib * context); void aac_printf(struct aac_dev *dev, u32 val); -int fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt); +int aac_fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt); int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry); void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); -int fib_complete(struct fib * context); +int aac_fib_complete(struct fib * context); #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) struct aac_dev *aac_init_adapter(struct aac_dev *dev); int aac_get_config_status(struct aac_dev *dev); @@ -1799,11 +1799,11 @@ unsigned int aac_command_normal(struct aac_queue * q); unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); int aac_command_thread(struct aac_dev * dev); int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); -int fib_adapter_complete(struct fib * fibptr, unsigned short size); +int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size); struct aac_driver_ident* aac_get_driver_ident(int devtype); int aac_get_adapter_info(struct aac_dev* dev); int aac_send_shutdown(struct aac_dev *dev); -int probe_container(struct aac_dev *dev, int cid); +int aac_probe_container(struct aac_dev *dev, int cid); extern int numacb; extern int acbsize; extern char aac_driver_version[]; diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 4fe79cd..47fefca 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -63,7 +63,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) unsigned size; int retval; - fibptr = fib_alloc(dev); + fibptr = aac_fib_alloc(dev); if(fibptr == NULL) { return -ENOMEM; } @@ -73,7 +73,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) * First copy in the header so that we can check the size field. */ if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) { - fib_free(fibptr); + aac_fib_free(fibptr); return -EFAULT; } /* @@ -110,13 +110,13 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) */ kfib->header.XferState = 0; } else { - retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr, + retval = aac_fib_send(le16_to_cpu(kfib->header.Command), fibptr, le16_to_cpu(kfib->header.Size) , FsaNormal, 1, 1, NULL, NULL); if (retval) { goto cleanup; } - if (fib_complete(fibptr) != 0) { + if (aac_fib_complete(fibptr) != 0) { retval = -EINVAL; goto cleanup; } @@ -138,7 +138,7 @@ cleanup: fibptr->hw_fib_pa = hw_fib_pa; fibptr->hw_fib = hw_fib; } - fib_free(fibptr); + aac_fib_free(fibptr); return retval; } @@ -464,10 +464,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) /* * Allocate and initialize a Fib then setup a BlockWrite command */ - if (!(srbfib = fib_alloc(dev))) { + if (!(srbfib = aac_fib_alloc(dev))) { return -ENOMEM; } - fib_init(srbfib); + aac_fib_init(srbfib); srbcmd = (struct aac_srb*) fib_data(srbfib); @@ -601,7 +601,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) srbcmd->count = cpu_to_le32(byte_count); psg->count = cpu_to_le32(sg_indx+1); - status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); + status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); } else { struct user_sgmap* upsg = &user_srbcmd->sg; struct sgmap* psg = &srbcmd->sg; @@ -649,7 +649,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) } srbcmd->count = cpu_to_le32(byte_count); psg->count = cpu_to_le32(sg_indx+1); - status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); + status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); } if (status != 0){ @@ -684,8 +684,8 @@ cleanup: for(i=0; i <= sg_indx; i++){ kfree(sg_list[i]); } - fib_complete(srbfib); - fib_free(srbfib); + aac_fib_complete(srbfib); + aac_fib_free(srbfib); return rcode; } diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 82821d3..1628d09 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -185,17 +185,17 @@ int aac_send_shutdown(struct aac_dev * dev) struct aac_close *cmd; int status; - fibctx = fib_alloc(dev); + fibctx = aac_fib_alloc(dev); if (!fibctx) return -ENOMEM; - fib_init(fibctx); + aac_fib_init(fibctx); cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); cmd->cid = cpu_to_le32(0xffffffff); - status = fib_send(ContainerCommand, + status = aac_fib_send(ContainerCommand, fibctx, sizeof(struct aac_close), FsaNormal, @@ -203,8 +203,8 @@ int aac_send_shutdown(struct aac_dev * dev) NULL, NULL); if (status == 0) - fib_complete(fibctx); - fib_free(fibctx); + aac_fib_complete(fibctx); + aac_fib_free(fibctx); return status; } @@ -427,7 +427,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) /* * Initialize the list of fibs */ - if(fib_setup(dev)<0){ + if (aac_fib_setup(dev) < 0) { kfree(dev->queues); return NULL; } diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 38d6d00..97354ba 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -67,27 +67,27 @@ static int fib_map_alloc(struct aac_dev *dev) } /** - * fib_map_free - free the fib objects + * aac_fib_map_free - free the fib objects * @dev: Adapter to free * * Free the PCI mappings and the memory allocated for FIB blocks * on this adapter. */ -void fib_map_free(struct aac_dev *dev) +void aac_fib_map_free(struct aac_dev *dev) { pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa); } /** - * fib_setup - setup the fibs + * aac_fib_setup - setup the fibs * @dev: Adapter to set up * * Allocate the PCI space for the fibs, map it and then intialise the * fib area, the unmapped fib data and also the free list */ -int fib_setup(struct aac_dev * dev) +int aac_fib_setup(struct aac_dev * dev) { struct fib *fibptr; struct hw_fib *hw_fib_va; @@ -134,14 +134,14 @@ int fib_setup(struct aac_dev * dev) } /** - * fib_alloc - allocate a fib + * aac_fib_alloc - allocate a fib * @dev: Adapter to allocate the fib for * * Allocate a fib from the adapter fib pool. If the pool is empty we * return NULL. */ -struct fib * fib_alloc(struct aac_dev *dev) +struct fib *aac_fib_alloc(struct aac_dev *dev) { struct fib * fibptr; unsigned long flags; @@ -170,14 +170,14 @@ struct fib * fib_alloc(struct aac_dev *dev) } /** - * fib_free - free a fib + * aac_fib_free - free a fib * @fibptr: fib to free up * * Frees up a fib and places it on the appropriate queue * (either free or timed out) */ -void fib_free(struct fib * fibptr) +void aac_fib_free(struct fib *fibptr) { unsigned long flags; @@ -188,7 +188,7 @@ void fib_free(struct fib * fibptr) fibptr->dev->timeout_fib = fibptr; } else { if (fibptr->hw_fib->header.XferState != 0) { - printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", + printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", (void*)fibptr, le32_to_cpu(fibptr->hw_fib->header.XferState)); } @@ -199,13 +199,13 @@ void fib_free(struct fib * fibptr) } /** - * fib_init - initialise a fib + * aac_fib_init - initialise a fib * @fibptr: The fib to initialize * * Set up the generic fib fields ready for use */ -void fib_init(struct fib *fibptr) +void aac_fib_init(struct fib *fibptr) { struct hw_fib *hw_fib = fibptr->hw_fib; @@ -362,7 +362,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f */ /** - * fib_send - send a fib to the adapter + * aac_fib_send - send a fib to the adapter * @command: Command to send * @fibptr: The fib * @size: Size of fib data area @@ -378,7 +378,9 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f * response FIB is received from the adapter. */ -int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data) +int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, + int priority, int wait, int reply, fib_callback callback, + void *callback_data) { struct aac_dev * dev = fibptr->dev; struct hw_fib * hw_fib = fibptr->hw_fib; @@ -493,7 +495,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority q->numpending++; *(q->headers.producer) = cpu_to_le32(index + 1); spin_unlock_irqrestore(q->lock, qflags); - dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index)); + dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index)); if (!(nointr & aac_config.irq_mod)) aac_adapter_notify(dev, AdapNormCmdQueue); } @@ -520,7 +522,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority list_del(&fibptr->queue); spin_unlock_irqrestore(q->lock, qflags); if (wait == -1) { - printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n" + printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n" "Usually a result of a PCI interrupt routing problem;\n" "update mother board BIOS or consider utilizing one of\n" "the SAFE mode kernel options (acpi, apic etc)\n"); @@ -624,7 +626,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) } /** - * fib_adapter_complete - complete adapter issued fib + * aac_fib_adapter_complete - complete adapter issued fib * @fibptr: fib to complete * @size: size of fib * @@ -632,7 +634,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) * the adapter. */ -int fib_adapter_complete(struct fib * fibptr, unsigned short size) +int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) { struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_dev * dev = fibptr->dev; @@ -683,20 +685,20 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size) } else { - printk(KERN_WARNING "fib_adapter_complete: Unknown xferstate detected.\n"); + printk(KERN_WARNING "aac_fib_adapter_complete: Unknown xferstate detected.\n"); BUG(); } return 0; } /** - * fib_complete - fib completion handler + * aac_fib_complete - fib completion handler * @fib: FIB to complete * * Will do all necessary work to complete a FIB. */ -int fib_complete(struct fib * fibptr) +int aac_fib_complete(struct fib *fibptr) { struct hw_fib * hw_fib = fibptr->hw_fib; @@ -995,14 +997,14 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) if (!dev || !dev->scsi_host_ptr) return; /* - * force reload of disk info via probe_container + * force reload of disk info via aac_probe_container */ if ((device_config_needed == CHANGE) && (dev->fsa_dev[container].valid == 1)) dev->fsa_dev[container].valid = 2; if ((device_config_needed == CHANGE) || (device_config_needed == ADD)) - probe_container(dev, container); + aac_probe_container(dev, container); device = scsi_device_lookup(dev->scsi_host_ptr, CONTAINER_TO_CHANNEL(container), CONTAINER_TO_ID(container), @@ -1104,7 +1106,7 @@ int aac_command_thread(struct aac_dev * dev) /* Handle Driver Notify Events */ aac_handle_aif(dev, fib); *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(fib, (u16)sizeof(u32)); + aac_fib_adapter_complete(fib, (u16)sizeof(u32)); } else { struct list_head *entry; /* The u32 here is important and intended. We are using @@ -1241,7 +1243,7 @@ int aac_command_thread(struct aac_dev * dev) * Set the status of this FIB */ *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(fib, sizeof(u32)); + aac_fib_adapter_complete(fib, sizeof(u32)); spin_unlock_irqrestore(&dev->fib_lock, flagv); /* Free up the remaining resources */ hw_fib_p = hw_fib_pool; diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index 439948e..f6bcb94 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -206,7 +206,7 @@ unsigned int aac_command_normal(struct aac_queue *q) * Set the status of this FIB */ *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(fib, sizeof(u32)); + aac_fib_adapter_complete(fib, sizeof(u32)); spin_lock_irqsave(q->lock, flags); } } diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 45fc171..9defee03 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -917,7 +917,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, aac_adapter_disable_int(aac); free_irq(pdev->irq, aac); out_unmap: - fib_map_free(aac); + aac_fib_map_free(aac); pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); kfree(aac->queues); iounmap(aac->regs.sa); @@ -951,7 +951,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) aac_send_shutdown(aac); aac_adapter_disable_int(aac); - fib_map_free(aac); + aac_fib_map_free(aac); pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); kfree(aac->queues); -- cgit v0.10.2 From bb08f92ebd75704e07d69bb9d8ee234d1a500b98 Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Wed, 1 Feb 2006 09:30:44 -0800 Subject: [SCSI] aacraid: use no_uld_attach flag Received From Mark Salyzyn. In order to support user tools accessing the array components (SMART, Mode Page information, Cache page adjustments, WWN determination, Firmware updates etc), we take advantage of the no_uld_attach flag and deprecate the code that filters Inquiries to block the requests to array components. The quirk prevents the sd layer from attaching to the components. We also took the opportunity to balance the queue depths based on the total adapter queue depth to the array devices to reduce the chances of starvation. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index b0f314e..a16f8de 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1465,7 +1465,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * itself. */ if (scmd_id(scsicmd) != host->this_id) { - if ((scsicmd->device->channel == 0) ){ + if ((scsicmd->device->channel == CONTAINER_CHANNEL)) { if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ scsicmd->result = DID_NO_CONNECT << 16; scsicmd->scsi_done(scsicmd); @@ -1935,33 +1935,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) case SRB_STATUS_ERROR_RECOVERY: case SRB_STATUS_PENDING: case SRB_STATUS_SUCCESS: - if(scsicmd->cmnd[0] == INQUIRY ){ - u8 b; - u8 b1; - /* We can't expose disk devices because we can't tell whether they - * are the raw container drives or stand alone drives. If they have - * the removable bit set then we should expose them though. - */ - b = (*(u8*)scsicmd->buffer)&0x1f; - b1 = ((u8*)scsicmd->buffer)[1]; - if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER - || (b==TYPE_DISK && (b1&0x80)) ){ - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; - /* - * We will allow disk devices if in RAID/SCSI mode and - * the channel is 2 - */ - } else if ((dev->raid_scsi_mode) && - (scmd_channel(scsicmd) == 2)) { - scsicmd->result = DID_OK << 16 | - COMMAND_COMPLETE << 8; - } else { - scsicmd->result = DID_NO_CONNECT << 16 | - COMMAND_COMPLETE << 8; - } - } else { - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; - } + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; break; case SRB_STATUS_DATA_OVERRUN: switch(scsicmd->cmnd[0]){ @@ -1981,28 +1955,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8; break; case INQUIRY: { - u8 b; - u8 b1; - /* We can't expose disk devices because we can't tell whether they - * are the raw container drives or stand alone drives - */ - b = (*(u8*)scsicmd->buffer)&0x0f; - b1 = ((u8*)scsicmd->buffer)[1]; - if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER - || (b==TYPE_DISK && (b1&0x80)) ){ - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; - /* - * We will allow disk devices if in RAID/SCSI mode and - * the channel is 2 - */ - } else if ((dev->raid_scsi_mode) && - (scmd_channel(scsicmd) == 2)) { - scsicmd->result = DID_OK << 16 | - COMMAND_COMPLETE << 8; - } else { - scsicmd->result = DID_NO_CONNECT << 16 | - COMMAND_COMPLETE << 8; - } + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; break; } default: diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 9defee03..2716178 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -385,21 +385,45 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, static int aac_slave_configure(struct scsi_device *sdev) { - struct Scsi_Host *host = sdev->host; if (sdev_channel(sdev) == CONTAINER_CHANNEL) { sdev->skip_ms_page_8 = 1; sdev->skip_ms_page_3f = 1; } + if ((sdev->type == TYPE_DISK) && + (sdev_channel(sdev) != CONTAINER_CHANNEL)) { + struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; + if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) + sdev->no_uld_attach = 1; + } + if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && + (sdev_channel(sdev) == CONTAINER_CHANNEL)) { + struct scsi_device * dev; + struct Scsi_Host *host = sdev->host; + unsigned num_lsu = 0; + unsigned num_one = 0; + unsigned depth; - if (sdev->tagged_supported) - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); - else + __shost_for_each_device(dev, host) { + if (dev->tagged_supported && (dev->type == TYPE_DISK) && + (sdev_channel(dev) == CONTAINER_CHANNEL)) + ++num_lsu; + else + ++num_one; + } + if (num_lsu == 0) + ++num_lsu; + depth = (host->can_queue - num_one) / num_lsu; + if (depth > 256) + depth = 256; + else if (depth < 2) + depth = 2; + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth); + if (!(((struct aac_dev *)host->hostdata)->adapter_info.options & + AAC_OPT_NEW_COMM)) + blk_queue_max_segment_size(sdev->request_queue, 65536); + } else scsi_adjust_queue_depth(sdev, 0, 1); - if (!(((struct aac_dev *)host->hostdata)->adapter_info.options - & AAC_OPT_NEW_COMM)) - blk_queue_max_segment_size(sdev->request_queue, 65536); - return 0; } @@ -874,7 +898,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, /* * max channel will be the physical channels plus 1 virtual channel - * all containers are on the virtual channel 0 + * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) * physical channels are address by their actual physical number+1 */ if (aac->nondasd_support == 1) -- cgit v0.10.2 From 7b7232f3fb5ecd7c30cb52df368070cc5f5ca614 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:06:49 -0600 Subject: [SCSI] iscsi update: cleanup iscsi class interface From: michaelc@cs.wisc.edu fujita.tomonori@lab.ntt.co.jp da-x@monatomic.org and err path fixup from: ogerlitz@voltaire.com This patch cleans up that interface by having the lld and class pass a iscsi_cls_session or iscsi_cls_conn between each other when the function is used by HW and SW iscsi llds. This way the lld does not have to remember if it has to send a handle or pointer and a handle or pointer to connection, session or host. This also has the class verify the session handle that gets passed from userspace instead of using the pointer passed into the kernel directly. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 780bfcc..d07d309 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -146,7 +146,7 @@ iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) spin_unlock_irqrestore(&session->lock, flags); set_bit(SUSPEND_BIT, &conn->suspend_tx); set_bit(SUSPEND_BIT, &conn->suspend_rx); - iscsi_conn_error(iscsi_handle(conn), err); + iscsi_conn_error(conn->cls_conn, err); } static inline int @@ -689,7 +689,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) break; if (!conn->in.datalen) { - rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, + rc = iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0); if (conn->login_mtask != mtask) { spin_lock(&session->lock); @@ -737,7 +737,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) if (!conn->in.datalen) { struct iscsi_mgmt_task *mtask; - rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, + rc = iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0); mtask = (struct iscsi_mgmt_task *) session->mgmt_cmds[conn->in.itt - @@ -761,7 +761,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)hdr); if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) - rc = iscsi_recv_pdu(iscsi_handle(conn), + rc = iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0); } else rc = ISCSI_ERR_PROTO; @@ -1044,7 +1044,7 @@ iscsi_data_recv(struct iscsi_conn *conn) goto exit; } - rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr, + rc = iscsi_recv_pdu(conn->cls_conn, conn->in.hdr, conn->data, conn->in.datalen); if (!rc && conn->datadgst_en && @@ -2428,19 +2428,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items) } static struct iscsi_cls_conn * -iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx) +iscsi_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) { + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); struct iscsi_session *session = iscsi_hostdata(shost->hostdata); struct iscsi_conn *conn; struct iscsi_cls_conn *cls_conn; - cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata), - conn_idx); + cls_conn = iscsi_create_conn(cls_session, conn_idx); if (!cls_conn) return NULL; conn = cls_conn->dd_data; + memset(conn, 0, sizeof(*conn)); - memset(conn, 0, sizeof(struct iscsi_conn)); + conn->cls_conn = cls_conn; conn->c_stage = ISCSI_CONN_INITIAL_STAGE; conn->in_progress = IN_PROGRESS_WAIT_HEADER; conn->id = conn_idx; @@ -2625,11 +2626,13 @@ iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn) } static int -iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh, - uint32_t transport_fd, int is_leading) +iscsi_conn_bind(struct iscsi_cls_session *cls_session, + struct iscsi_cls_conn *cls_conn, uint32_t transport_fd, + int is_leading) { - struct iscsi_session *session = iscsi_ptr(sessionh); - struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = iscsi_ptr(connh); + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; struct sock *sk; struct socket *sock; int err; @@ -2703,9 +2706,9 @@ iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh, } static int -iscsi_conn_start(iscsi_connh_t connh) +iscsi_conn_start(struct iscsi_cls_conn *cls_conn) { - struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_session *session = conn->session; struct sock *sk; @@ -2754,9 +2757,9 @@ iscsi_conn_start(iscsi_connh_t connh) } static void -iscsi_conn_stop(iscsi_connh_t connh, int flag) +iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) { - struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_session *session = conn->session; struct sock *sk; unsigned long flags; @@ -3253,9 +3256,9 @@ static struct scsi_host_template iscsi_sht = { static struct iscsi_transport iscsi_tcp_transport; -static struct Scsi_Host * +static struct iscsi_cls_session * iscsi_session_create(struct scsi_transport_template *scsit, - uint32_t initial_cmdsn) + uint32_t initial_cmdsn, uint32_t *sid) { struct Scsi_Host *shost; struct iscsi_session *session; @@ -3275,6 +3278,7 @@ iscsi_session_create(struct scsi_transport_template *scsit, session->exp_cmdsn = initial_cmdsn + 1; session->max_cmdsn = initial_cmdsn + 1; session->max_r2t = 1; + *sid = shost->host_no; /* initialize SCSI PDU commands pool */ if (iscsi_pool_init(&session->cmdpool, session->cmds_max, @@ -3311,7 +3315,7 @@ iscsi_session_create(struct scsi_transport_template *scsit, if (iscsi_r2tpool_alloc(session)) goto r2tpool_alloc_fail; - return shost; + return hostdata_session(shost->hostdata); r2tpool_alloc_fail: for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) @@ -3321,12 +3325,14 @@ immdata_alloc_fail: mgmtpool_alloc_fail: iscsi_pool_free(&session->cmdpool, (void**)session->cmds); cmdpool_alloc_fail: + iscsi_transport_destroy_session(shost); return NULL; } static void -iscsi_session_destroy(struct Scsi_Host *shost) +iscsi_session_destroy(struct iscsi_cls_session *cls_session) { + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); struct iscsi_session *session = iscsi_hostdata(shost->hostdata); int cmd_i; struct iscsi_data_task *dtask, *n; @@ -3350,10 +3356,10 @@ iscsi_session_destroy(struct Scsi_Host *shost) } static int -iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, +iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, uint32_t value) { - struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_session *session = conn->session; spin_lock_bh(&session->lock); @@ -3495,9 +3501,10 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, } static int -iscsi_session_get_param(struct Scsi_Host *shost, +iscsi_session_get_param(struct iscsi_cls_session *cls_session, enum iscsi_param param, uint32_t *value) { + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); struct iscsi_session *session = iscsi_hostdata(shost->hostdata); switch(param) { @@ -3539,9 +3546,10 @@ iscsi_session_get_param(struct Scsi_Host *shost, } static int -iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value) +iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, + enum iscsi_param param, uint32_t *value) { - struct iscsi_conn *conn = data; + struct iscsi_conn *conn = cls_conn->dd_data; switch(param) { case ISCSI_PARAM_MAX_RECV_DLENGTH: @@ -3564,9 +3572,9 @@ iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value) } static void -iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) +iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) { - struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_conn *conn = cls_conn->dd_data; stats->txdata_octets = conn->txdata_octets; stats->rxdata_octets = conn->rxdata_octets; @@ -3587,10 +3595,10 @@ iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) } static int -iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data, - uint32_t data_size) +iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size) { - struct iscsi_conn *conn = iscsi_ptr(connh); + struct iscsi_conn *conn = cls_conn->dd_data; int rc; mutex_lock(&conn->xmitmutex); diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index f95e61b..6766b81 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -113,7 +113,10 @@ struct iscsi_tcp_recv { int datadgst; }; +struct iscsi_cls_conn; + struct iscsi_conn { + struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ struct iscsi_hdr hdr; /* header placeholder */ char hdrext[4*sizeof(__u16) + sizeof(__u32)]; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 59a1c9d..b618685 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -164,9 +164,43 @@ static struct mempool_zone *z_reply; #define Z_MAX_ERROR 16 #define Z_HIWAT_ERROR 12 +static LIST_HEAD(sesslist); +static DEFINE_SPINLOCK(sesslock); static LIST_HEAD(connlist); static DEFINE_SPINLOCK(connlock); +static struct iscsi_cls_session *iscsi_session_lookup(uint64_t handle) +{ + unsigned long flags; + struct iscsi_cls_session *sess; + + spin_lock_irqsave(&sesslock, flags); + list_for_each_entry(sess, &sesslist, sess_list) { + if (sess == iscsi_ptr(handle)) { + spin_unlock_irqrestore(&sesslock, flags); + return sess; + } + } + spin_unlock_irqrestore(&sesslock, flags); + return NULL; +} + +static struct iscsi_cls_conn *iscsi_conn_lookup(uint64_t handle) +{ + unsigned long flags; + struct iscsi_cls_conn *conn; + + spin_lock_irqsave(&connlock, flags); + list_for_each_entry(conn, &connlist, conn_list) { + if (conn == iscsi_ptr(handle)) { + spin_unlock_irqrestore(&connlock, flags); + return conn; + } + } + spin_unlock_irqrestore(&connlock, flags); + return NULL; +} + /* * The following functions can be used by LLDs that allocate * their own scsi_hosts or by software iscsi LLDs @@ -365,6 +399,7 @@ iscsi_transport_create_session(struct scsi_transport_template *scsit, { struct iscsi_cls_session *session; struct Scsi_Host *shost; + unsigned long flags; shost = scsi_host_alloc(transport->host_template, hostdata_privsize(transport)); @@ -389,6 +424,9 @@ iscsi_transport_create_session(struct scsi_transport_template *scsit, goto remove_host; *(unsigned long*)shost->hostdata = (unsigned long)session; + spin_lock_irqsave(&sesslock, flags); + list_add(&session->sess_list, &sesslist); + spin_unlock_irqrestore(&sesslock, flags); return shost; remove_host: @@ -410,9 +448,13 @@ EXPORT_SYMBOL_GPL(iscsi_transport_create_session); int iscsi_transport_destroy_session(struct Scsi_Host *shost) { struct iscsi_cls_session *session; + unsigned long flags; scsi_remove_host(shost); session = hostdata_session(shost->hostdata); + spin_lock_irqsave(&sesslock, flags); + list_del(&session->sess_list); + spin_unlock_irqrestore(&sesslock, flags); iscsi_destroy_session(session); /* ref from host alloc */ scsi_host_put(shost); @@ -424,22 +466,6 @@ EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session); /* * iscsi interface functions */ -static struct iscsi_cls_conn* -iscsi_if_find_conn(uint64_t key) -{ - unsigned long flags; - struct iscsi_cls_conn *conn; - - spin_lock_irqsave(&connlock, flags); - list_for_each_entry(conn, &connlist, conn_list) - if (conn->connh == key) { - spin_unlock_irqrestore(&connlock, flags); - return conn; - } - spin_unlock_irqrestore(&connlock, flags); - return NULL; -} - static struct iscsi_internal * iscsi_if_transport_lookup(struct iscsi_transport *tt) { @@ -559,25 +585,21 @@ iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) return 0; } -int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, +int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size) { struct nlmsghdr *nlh; struct sk_buff *skb; struct iscsi_uevent *ev; - struct iscsi_cls_conn *conn; char *pdu; int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + data_size); - conn = iscsi_if_find_conn(connh); - BUG_ON(!conn); - mempool_zone_complete(conn->z_pdu); skb = mempool_zone_get_skb(conn->z_pdu); if (!skb) { - iscsi_conn_error(connh, ISCSI_ERR_CONN_FAILED); + iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED); dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver " "control PDU: OOM\n"); return -ENOMEM; @@ -590,7 +612,7 @@ int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, ev->type = ISCSI_KEVENT_RECV_PDU; if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) ev->iferror = -ENOMEM; - ev->r.recv_req.conn_handle = connh; + ev->r.recv_req.conn_handle = iscsi_handle(conn); pdu = (char*)ev + sizeof(*ev); memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); @@ -599,17 +621,13 @@ int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, } EXPORT_SYMBOL_GPL(iscsi_recv_pdu); -void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error) +void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) { struct nlmsghdr *nlh; struct sk_buff *skb; struct iscsi_uevent *ev; - struct iscsi_cls_conn *conn; int len = NLMSG_SPACE(sizeof(*ev)); - conn = iscsi_if_find_conn(connh); - BUG_ON(!conn); - mempool_zone_complete(conn->z_error); skb = mempool_zone_get_skb(conn->z_error); @@ -626,7 +644,7 @@ void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error) if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) ev->iferror = -ENOMEM; ev->r.connerror.error = error; - ev->r.connerror.conn_handle = connh; + ev->r.connerror.conn_handle = iscsi_handle(conn); iscsi_unicast_skb(conn->z_error, skb); @@ -677,7 +695,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, ISCSI_STATS_CUSTOM_MAX); int err = 0; - conn = iscsi_if_find_conn(ev->u.get_stats.conn_handle); + conn = iscsi_conn_lookup(ev->u.get_stats.conn_handle); if (!conn) return -EEXIST; @@ -707,7 +725,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, ((char*)evstat + sizeof(*evstat)); memset(stats, 0, sizeof(*stats)); - transport->get_stats(ev->u.get_stats.conn_handle, stats); + transport->get_stats(conn, stats); actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) + sizeof(struct iscsi_stats) + sizeof(struct iscsi_stats_custom) * @@ -727,58 +745,34 @@ static int iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) { struct iscsi_transport *transport = priv->iscsi_transport; - struct Scsi_Host *shost; - - if (!transport->create_session) - return -EINVAL; + struct iscsi_cls_session *session; + uint32_t sid; - shost = transport->create_session(&priv->t, - ev->u.c_session.initial_cmdsn); - if (!shost) + session = transport->create_session(&priv->t, + ev->u.c_session.initial_cmdsn, + &sid); + if (!session) return -ENOMEM; - ev->r.c_session_ret.session_handle = iscsi_handle(iscsi_hostdata(shost->hostdata)); - ev->r.c_session_ret.sid = shost->host_no; + ev->r.c_session_ret.session_handle = iscsi_handle(session); + ev->r.c_session_ret.sid = sid; return 0; } static int -iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) +iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) { - struct iscsi_transport *transport = priv->iscsi_transport; - - struct Scsi_Host *shost; - - if (!transport->destroy_session) - return -EINVAL; - - shost = scsi_host_lookup(ev->u.d_session.sid); - if (shost == ERR_PTR(-ENXIO)) - return -EEXIST; - - if (transport->destroy_session) - transport->destroy_session(shost); - /* ref from host lookup */ - scsi_host_put(shost); - return 0; -} - -static int -iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev){ - struct Scsi_Host *shost; struct iscsi_cls_conn *conn; + struct iscsi_cls_session *session; unsigned long flags; - if (!transport->create_conn) + session = iscsi_session_lookup(ev->u.c_conn.session_handle); + if (!session) return -EINVAL; - shost = scsi_host_lookup(ev->u.c_conn.sid); - if (shost == ERR_PTR(-ENXIO)) - return -EEXIST; - - conn = transport->create_conn(shost, ev->u.c_conn.cid); + conn = transport->create_conn(session, ev->u.c_conn.cid); if (!conn) - goto release_ref; + return -ENOMEM; conn->z_pdu = mempool_zone_init(Z_MAX_PDU, NLMSG_SPACE(sizeof(struct iscsi_uevent) + @@ -800,14 +794,13 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) goto free_pdu_pool; } - ev->r.handle = conn->connh = iscsi_handle(conn->dd_data); + ev->r.handle = iscsi_handle(conn); spin_lock_irqsave(&connlock, flags); list_add(&conn->conn_list, &connlist); conn->active = 1; spin_unlock_irqrestore(&connlock, flags); - scsi_host_put(shost); return 0; free_pdu_pool: @@ -815,8 +808,6 @@ free_pdu_pool: destroy_conn: if (transport->destroy_conn) transport->destroy_conn(conn->dd_data); -release_ref: - scsi_host_put(shost); return -ENOMEM; } @@ -827,13 +818,9 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev struct iscsi_cls_conn *conn; struct mempool_zone *z_error, *z_pdu; - conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle); + conn = iscsi_conn_lookup(ev->u.d_conn.conn_handle); if (!conn) - return -EEXIST; - - if (!transport->destroy_conn) return -EINVAL; - spin_lock_irqsave(&connlock, flags); conn->active = 0; list_del(&conn->conn_list); @@ -858,6 +845,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct iscsi_uevent *ev = NLMSG_DATA(nlh); struct iscsi_transport *transport = NULL; struct iscsi_internal *priv; + struct iscsi_cls_session *session; + struct iscsi_cls_conn *conn; if (NETLINK_CREDS(skb)->uid) return -EPERM; @@ -867,6 +856,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return -EINVAL; transport = priv->iscsi_transport; + if (!try_module_get(transport->owner)) + return -EINVAL; + daemon_pid = NETLINK_CREDS(skb)->pid; switch (nlh->nlmsg_type) { @@ -874,7 +866,11 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) err = iscsi_if_create_session(priv, ev); break; case ISCSI_UEVENT_DESTROY_SESSION: - err = iscsi_if_destroy_session(priv, ev); + session = iscsi_session_lookup(ev->u.d_session.session_handle); + if (session) + transport->destroy_session(session); + else + err = -EINVAL; break; case ISCSI_UEVENT_CREATE_CONN: err = iscsi_if_create_conn(transport, ev); @@ -883,41 +879,48 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) err = iscsi_if_destroy_conn(transport, ev); break; case ISCSI_UEVENT_BIND_CONN: - if (!iscsi_if_find_conn(ev->u.b_conn.conn_handle)) - return -EEXIST; - ev->r.retcode = transport->bind_conn( - ev->u.b_conn.session_handle, - ev->u.b_conn.conn_handle, - ev->u.b_conn.transport_fd, - ev->u.b_conn.is_leading); + session = iscsi_session_lookup(ev->u.b_conn.session_handle); + conn = iscsi_conn_lookup(ev->u.b_conn.conn_handle); + + if (session && conn) + ev->r.retcode = transport->bind_conn(session, conn, + ev->u.b_conn.transport_fd, + ev->u.b_conn.is_leading); + else + err = -EINVAL; break; case ISCSI_UEVENT_SET_PARAM: - if (!iscsi_if_find_conn(ev->u.set_param.conn_handle)) - return -EEXIST; - ev->r.retcode = transport->set_param( - ev->u.set_param.conn_handle, - ev->u.set_param.param, ev->u.set_param.value); + conn = iscsi_conn_lookup(ev->u.set_param.conn_handle); + if (conn) + ev->r.retcode = transport->set_param(conn, + ev->u.set_param.param, ev->u.set_param.value); + else + err = -EINVAL; break; case ISCSI_UEVENT_START_CONN: - if (!iscsi_if_find_conn(ev->u.start_conn.conn_handle)) - return -EEXIST; - ev->r.retcode = transport->start_conn( - ev->u.start_conn.conn_handle); + conn = iscsi_conn_lookup(ev->u.start_conn.conn_handle); + if (conn) + ev->r.retcode = transport->start_conn(conn); + else + err = -EINVAL; + break; case ISCSI_UEVENT_STOP_CONN: - if (!iscsi_if_find_conn(ev->u.stop_conn.conn_handle)) - return -EEXIST; - transport->stop_conn(ev->u.stop_conn.conn_handle, - ev->u.stop_conn.flag); + conn = iscsi_conn_lookup(ev->u.stop_conn.conn_handle); + if (conn) + transport->stop_conn(conn, ev->u.stop_conn.flag); + else + err = -EINVAL; break; case ISCSI_UEVENT_SEND_PDU: - if (!iscsi_if_find_conn(ev->u.send_pdu.conn_handle)) - return -EEXIST; - ev->r.retcode = transport->send_pdu( - ev->u.send_pdu.conn_handle, - (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), - (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, - ev->u.send_pdu.data_size); + conn = iscsi_conn_lookup(ev->u.send_pdu.conn_handle); + if (conn) + ev->r.retcode = transport->send_pdu(conn, + (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), + (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, + ev->u.send_pdu.data_size); + else + err = -EINVAL; break; case ISCSI_UEVENT_GET_STATS: err = iscsi_if_get_stats(transport, skb, nlh); @@ -927,6 +930,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) break; } + module_put(transport->owner); return err; } @@ -997,7 +1001,7 @@ show_conn_int_param_##param(struct class_device *cdev, char *buf) \ struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ struct iscsi_transport *t = conn->transport; \ \ - t->get_conn_param(conn->dd_data, param, &value); \ + t->get_conn_param(conn, param, &value); \ return snprintf(buf, 20, format"\n", value); \ } @@ -1024,10 +1028,9 @@ show_session_int_param_##param(struct class_device *cdev, char *buf) \ { \ uint32_t value = 0; \ struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ - struct Scsi_Host *shost = iscsi_session_to_shost(session); \ struct iscsi_transport *t = session->transport; \ \ - t->get_session_param(shost, param, &value); \ + t->get_session_param(session, param, &value); \ return snprintf(buf, 20, format"\n", value); \ } diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 3e5cb5a..e5618b9 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -163,9 +163,6 @@ enum iscsi_param { }; #define ISCSI_PARAM_MAX 14 -typedef uint64_t iscsi_sessionh_t; /* iSCSI Data-Path session handle */ -typedef uint64_t iscsi_connh_t; /* iSCSI Data-Path connection handle */ - #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) #define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata)) diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 16602a5..b41cf07 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -63,25 +63,28 @@ struct iscsi_transport { int max_lun; unsigned int max_conn; unsigned int max_cmd_len; - struct Scsi_Host *(*create_session) (struct scsi_transport_template *t, - uint32_t initial_cmdsn); - void (*destroy_session) (struct Scsi_Host *shost); - struct iscsi_cls_conn *(*create_conn) (struct Scsi_Host *shost, + struct iscsi_cls_session *(*create_session) + (struct scsi_transport_template *t, uint32_t sn, uint32_t *sid); + void (*destroy_session) (struct iscsi_cls_session *session); + struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, uint32_t cid); - int (*bind_conn) (iscsi_sessionh_t session, iscsi_connh_t conn, + int (*bind_conn) (struct iscsi_cls_session *session, + struct iscsi_cls_conn *cls_conn, uint32_t transport_fd, int is_leading); - int (*start_conn) (iscsi_connh_t conn); - void (*stop_conn) (iscsi_connh_t conn, int flag); + int (*start_conn) (struct iscsi_cls_conn *conn); + void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); void (*destroy_conn) (struct iscsi_cls_conn *conn); - int (*set_param) (iscsi_connh_t conn, enum iscsi_param param, + int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, uint32_t value); - int (*get_conn_param) (void *conndata, enum iscsi_param param, + int (*get_conn_param) (struct iscsi_cls_conn *conn, + enum iscsi_param param, uint32_t *value); - int (*get_session_param) (struct Scsi_Host *shost, + int (*get_session_param) (struct iscsi_cls_session *session, enum iscsi_param param, uint32_t *value); - int (*send_pdu) (iscsi_connh_t conn, struct iscsi_hdr *hdr, + int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size); - void (*get_stats) (iscsi_connh_t conn, struct iscsi_stats *stats); + void (*get_stats) (struct iscsi_cls_conn *conn, + struct iscsi_stats *stats); }; /* @@ -93,15 +96,14 @@ extern int iscsi_unregister_transport(struct iscsi_transport *tt); /* * control plane upcalls */ -extern void iscsi_conn_error(iscsi_connh_t conn, enum iscsi_err error); -extern int iscsi_recv_pdu(iscsi_connh_t conn, struct iscsi_hdr *hdr, +extern void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error); +extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size); struct iscsi_cls_conn { struct list_head conn_list; /* item in connlist */ void *dd_data; /* LLD private data */ struct iscsi_transport *transport; - iscsi_connh_t connh; int active; /* must be accessed with the connlock */ struct device dev; /* sysfs transport/container device */ struct mempool_zone *z_error; @@ -113,7 +115,7 @@ struct iscsi_cls_conn { container_of(_dev, struct iscsi_cls_conn, dev) struct iscsi_cls_session { - struct list_head list; /* item in session_list */ + struct list_head sess_list; /* item in session_list */ struct iscsi_transport *transport; struct device dev; /* sysfs transport/container device */ }; -- cgit v0.10.2 From 5b940adf5b341b12dbb94e7cbdb416b35f52017b Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:06:56 -0600 Subject: [SCSI] iscsi update: pass correct skb to skb_trim >From da-x@monatomic.org: Wrong skb is passed to skb_trim in iscsi_if_get_stats. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index b618685..79ca29e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -680,8 +680,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, } static int -iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, - struct nlmsghdr *nlh) +iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) { struct iscsi_uevent *ev = NLMSG_DATA(nlh); struct iscsi_stats *stats; @@ -732,7 +731,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, stats->custom_length); actual_size -= sizeof(*nlhstat); actual_size = NLMSG_LENGTH(actual_size); - skb_trim(skb, NLMSG_ALIGN(actual_size)); + skb_trim(skbstat, NLMSG_ALIGN(actual_size)); nlhstat->nlmsg_len = actual_size; err = iscsi_unicast_skb(conn->z_pdu, skbstat); @@ -923,7 +922,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) err = -EINVAL; break; case ISCSI_UEVENT_GET_STATS: - err = iscsi_if_get_stats(transport, skb, nlh); + err = iscsi_if_get_stats(transport, nlh); break; default: err = -EINVAL; -- cgit v0.10.2 From 142e301fc818de9b116706835cd9fc864e73f203 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:06:58 -0600 Subject: [SCSI] iscsi update: setup pool before using >From andmike@us.ibm.com: Ensure that pool data is setup prior to calling mempool_create as it will call the the alloc function during create. Signed-off-by: Mike Anderson Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 79ca29e..448fd78 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -530,6 +530,12 @@ mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) if (!zp) return NULL; + zp->size = size; + zp->hiwat = hiwat; + INIT_LIST_HEAD(&zp->freequeue); + spin_lock_init(&zp->freelock); + atomic_set(&zp->allocated, 0); + zp->pool = mempool_create(max, mempool_zone_alloc_skb, mempool_zone_free_skb, zp); if (!zp->pool) { @@ -537,13 +543,6 @@ mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) return NULL; } - zp->size = size; - zp->hiwat = hiwat; - - INIT_LIST_HEAD(&zp->freequeue); - spin_lock_init(&zp->freelock); - atomic_set(&zp->allocated, 0); - return zp; } -- cgit v0.10.2 From ee7f8e405342722e42c15fe8e841a679f8951eea Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:07:01 -0600 Subject: [SCSI] iscsi update: set deamon pid earlier >From michaelc@cs.wisc.edu: If the transport lookup fails we set the daemon pid too late. This can cause us deadlock since the netlink code will think we meant to call back into our iscsi_if_rx function. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 448fd78..7fb6918 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -846,9 +846,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct iscsi_cls_session *session; struct iscsi_cls_conn *conn; - if (NETLINK_CREDS(skb)->uid) - return -EPERM; - priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); if (!priv) return -EINVAL; @@ -857,8 +854,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (!try_module_get(transport->owner)) return -EINVAL; - daemon_pid = NETLINK_CREDS(skb)->pid; - switch (nlh->nlmsg_type) { case ISCSI_UEVENT_CREATE_SESSION: err = iscsi_if_create_session(priv, ev); @@ -934,7 +929,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) /* Get message from skb (based on rtnetlink_rcv_skb). Each message is * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are - * discarded silently. */ + * or invalid creds discarded silently. */ static void iscsi_if_rx(struct sock *sk, int len) { @@ -942,6 +937,12 @@ iscsi_if_rx(struct sock *sk, int len) mutex_lock(&rx_queue_mutex); while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { + if (NETLINK_CREDS(skb)->uid) { + skb_pull(skb, skb->len); + goto free_skb; + } + daemon_pid = NETLINK_CREDS(skb)->pid; + while (skb->len >= NLMSG_SPACE(0)) { int err; uint32_t rlen; @@ -953,10 +954,12 @@ iscsi_if_rx(struct sock *sk, int len) skb->len < nlh->nlmsg_len) { break; } + ev = NLMSG_DATA(nlh); rlen = NLMSG_ALIGN(nlh->nlmsg_len); if (rlen > skb->len) rlen = skb->len; + err = iscsi_if_recv_msg(skb, nlh); if (err) { ev->type = ISCSI_KEVENT_IF_ERROR; @@ -980,6 +983,7 @@ iscsi_if_rx(struct sock *sk, int len) } while (err < 0 && err != -ECONNREFUSED); skb_pull(skb, rlen); } +free_skb: kfree_skb(skb); } mutex_unlock(&rx_queue_mutex); -- cgit v0.10.2 From 1fd459e367657f595ddf192b9a46298e18d4fc13 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:07:03 -0600 Subject: [SCSI] iscsi update: rm conn lock >From erezz@voltaire.com: rm conn->lock since it is not used anymore. The dataqueue is protected by the session lock and xmitmutex. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index d07d309..0cd78b1 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -244,12 +244,10 @@ iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) if (sc->sc_data_direction == DMA_TO_DEVICE) { struct iscsi_data_task *dtask, *n; /* WRITE: cleanup Data-Out's if any */ - spin_lock(&conn->lock); list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { list_del(&dtask->item); mempool_free(dtask, ctask->datapool); } - spin_unlock(&conn->lock); } ctask->xmstate = XMSTATE_IDLE; ctask->r2t = NULL; @@ -2453,8 +2451,6 @@ iscsi_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; - spin_lock_init(&conn->lock); - /* initialize general xmit PDU commands queue */ conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*), GFP_KERNEL, NULL); diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index 6766b81..ba26741 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -146,7 +146,6 @@ struct iscsi_conn { struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ - spinlock_t lock; /* FIXME: to be removed */ /* old values for socket callbacks */ void (*old_data_ready)(struct sock *, int); -- cgit v0.10.2 From 351f739e68e97a0316136a5bda145b952d99a989 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:07:06 -0600 Subject: [SCSI] iscsi update: set correct state at creation time >From erezz@voltaire.com: We are still in ISCSI_STATE_FREE state at create time. The addition of the first connection puts us in ISCSI_STATE_LOGGED_IN. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 0cd78b1..579eecf 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -3267,7 +3267,7 @@ iscsi_session_create(struct scsi_transport_template *scsit, session = iscsi_hostdata(shost->hostdata); memset(session, 0, sizeof(struct iscsi_session)); session->host = shost; - session->state = ISCSI_STATE_LOGGED_IN; + session->state = ISCSI_STATE_FREE; session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; session->cmds_max = ISCSI_XMIT_CMDS_MAX; session->cmdsn = initial_cmdsn; -- cgit v0.10.2 From b36ae07cb7757bd3eabd13c79844083dccac2f77 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:07:09 -0600 Subject: [SCSI] iscsi update: fix mgmt pool err path release >From ogerlitz@voltaire.com: mgmtpool shoild be frees in immdata_alloc_fail label. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 579eecf..ff79e68 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -3316,8 +3316,8 @@ iscsi_session_create(struct scsi_transport_template *scsit, r2tpool_alloc_fail: for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) kfree(session->mgmt_cmds[cmd_i]->data); - iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); immdata_alloc_fail: + iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); mgmtpool_alloc_fail: iscsi_pool_free(&session->cmdpool, (void**)session->cmds); cmdpool_alloc_fail: -- cgit v0.10.2 From 28e5554df63085be3b8bd2aee6ddbc479f0d136e Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:07:11 -0600 Subject: [SCSI] iscsi update: use gfp_t Use gfp_t. I accidentally removed this in our last update. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 7fb6918..55860d2 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -489,7 +489,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) } static void* -mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) +mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) { struct mempool_zone *zone = pool_data; -- cgit v0.10.2 From b5b81016538cf84a10c80438b7aa750dd375ba93 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 1 Feb 2006 21:07:14 -0600 Subject: [SCSI] iscsi update: rm unused sessions list rm unused sessions list. This patch is last becuase I was not sure if this patchset was going to be applied over the kmalloc2kzalloc one by JesS. If it is then this patch will not apply and can be dropped for now. I will resend later when things setttle down. Signed-off-by: Mike Christie Signed-off-by: Alex Aizman Signed-off-by: Dmitry Yusupov Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 55860d2..71e54a6 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -39,10 +39,6 @@ struct iscsi_internal { struct iscsi_transport *iscsi_transport; struct list_head list; /* - * List of sessions for this transport - */ - struct list_head sessions; - /* * based on transport capabilities, at register time we set these * bits to tell the transport class it wants attributes displayed * in sysfs or that it can support different iSCSI Data-Path @@ -1126,7 +1122,6 @@ iscsi_register_transport(struct iscsi_transport *tt) return NULL; memset(priv, 0, sizeof(*priv)); INIT_LIST_HEAD(&priv->list); - INIT_LIST_HEAD(&priv->sessions); priv->iscsi_transport = tt; priv->cdev.class = &iscsi_transport_class; -- cgit v0.10.2 From 096f7a2a094af3007937d6fd21560e28dca0994d Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:30 -0700 Subject: [SCSI] fusion - mptctl - MPTCOMMAND - adding function types. This adds support for new function types in the existing MPTCOMMAND ioctl. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index bdf7099..70a812a 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1817,6 +1817,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: case MPI_FUNCTION_FW_DOWNLOAD: case MPI_FUNCTION_FC_PRIMITIVE_SEND: + case MPI_FUNCTION_TOOLBOX: + case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: break; case MPI_FUNCTION_SCSI_IO_REQUEST: @@ -1888,6 +1890,25 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) } break; + case MPI_FUNCTION_SMP_PASSTHROUGH: + /* Check mf->PassthruFlags to determine if + * transfer is ImmediateMode or not. + * Immediate mode returns data in the ReplyFrame. + * Else, we are sending request and response data + * in two SGLs at the end of the mf. + */ + break; + + case MPI_FUNCTION_SATA_PASSTHROUGH: + if (!ioc->sh) { + printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + "SCSI driver is not loaded. \n", + __FILE__, __LINE__); + rc = -EFAULT; + goto done_free_mem; + } + break; + case MPI_FUNCTION_RAID_ACTION: /* Just add a SGE */ -- cgit v0.10.2 From 9cc1cfbc67d77164f5b612fcf833460eca4d81e9 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:33 -0700 Subject: [SCSI] fusion - mptctl - adding support for bus_type=SAS Add bus_type recognization in ioctl path for SAS. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 70a812a..1a1bc66 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1145,7 +1145,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) /* Fill in the data and return the structure to the calling * program */ - if (ioc->bus_type == FC) + if (ioc->bus_type == SAS) + karg->adapterType = MPT_IOCTL_INTERFACE_SAS; + else if (ioc->bus_type == FC) karg->adapterType = MPT_IOCTL_INTERFACE_FC; else karg->adapterType = MPT_IOCTL_INTERFACE_SCSI; @@ -2391,7 +2393,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) karg.base_io_addr = pci_resource_start(pdev, 0); - if (ioc->bus_type == FC) + if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) karg.bus_phys_width = HP_BUS_WIDTH_UNK; else karg.bus_phys_width = HP_BUS_WIDTH_16; @@ -2480,7 +2482,7 @@ mptctl_hp_targetinfo(unsigned long arg) /* There is nothing to do for FCP parts. */ - if (ioc->bus_type == FC) + if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) return 0; if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL)) diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index 518996e..a2f8a97 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h @@ -169,8 +169,10 @@ struct mpt_ioctl_pci_info2 { * Read only. * Data starts at offset 0xC */ -#define MPT_IOCTL_INTERFACE_FC (0x01) #define MPT_IOCTL_INTERFACE_SCSI (0x00) +#define MPT_IOCTL_INTERFACE_FC (0x01) +#define MPT_IOCTL_INTERFACE_FC_IP (0x02) +#define MPT_IOCTL_INTERFACE_SAS (0x03) #define MPT_IOCTL_VERSION_LENGTH (32) struct mpt_ioctl_iocinfo { -- cgit v0.10.2 From 86a7dcaae9c67a344e51190734b98684072d181c Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:37 -0700 Subject: [SCSI] fusion - mtctl - change to wait_event_timeout Change from using wait_event_interruptible_timeout to wait_event_timeout. Also delete white space and duplicate line of code. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 1a1bc66..8e2369f 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -385,18 +385,18 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) } /* Now wait for the command to complete */ - ii = wait_event_interruptible_timeout(mptctl_wait, + ii = wait_event_timeout(mptctl_wait, ioctl->wait_done == 1, HZ*5 /* 5 second timeout */); if(ii <=0 && (ioctl->wait_done != 1 )) { + mpt_free_msg_frame(hd->ioc, mf); ioctl->wait_done = 0; retval = -1; /* return failure */ } mptctl_bus_reset_done: - mpt_free_msg_frame(hd->ioc, mf); mptctl_free_tm_flags(ioctl->ioc); return retval; } @@ -807,7 +807,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) mpt_put_msg_frame(mptctl_id, iocp, mf); /* Now wait for the command to complete */ - ret = wait_event_interruptible_timeout(mptctl_wait, + ret = wait_event_timeout(mptctl_wait, iocp->ioctl->wait_done == 1, HZ*60); @@ -1172,12 +1172,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); } else if (cim_rev == 2) { - /* Get the PCI bus, device, function and segment ID numbers + /* Get the PCI bus, device, function and segment ID numbers for the IOC */ karg->pciInfo.u.bits.busNumber = pdev->bus->number; karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); - karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); karg->pciInfo.segmentID = pci_domain_nr(pdev->bus); } @@ -2153,7 +2152,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) /* Now wait for the command to complete */ timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT; - timeout = wait_event_interruptible_timeout(mptctl_wait, + timeout = wait_event_timeout(mptctl_wait, ioc->ioctl->wait_done == 1, HZ*timeout); -- cgit v0.10.2 From 5b5ef4f617f1706a23b0433d89a9c02ceb0980a5 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:40 -0700 Subject: [SCSI] fusion - mptctl - Event Log Fix Use the hard coded value MPTCTL_EVENT_LOG_SIZE to fix bug where in certain cases, the ioc->eventLogSize was initialized. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 9a2c760..a3751d8 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -6142,7 +6142,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply if (ioc->events && (ioc->eventTypes & ( 1 << event))) { int idx; - idx = ioc->eventContext % ioc->eventLogSize; + idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; ioc->events[idx].event = event; ioc->events[idx].eventContext = ioc->eventContext; diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 8e2369f..b603fb8 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1501,7 +1501,7 @@ mptctl_eventquery (unsigned long arg) return -ENODEV; } - karg.eventEntries = ioc->eventLogSize; + karg.eventEntries = MPTCTL_EVENT_LOG_SIZE; karg.eventTypes = ioc->eventTypes; /* Copy the data from kernel memory to user memory @@ -1551,7 +1551,6 @@ mptctl_eventenable (unsigned long arg) memset(ioc->events, 0, sz); ioc->alloc_total += sz; - ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE; ioc->eventContext = 0; } @@ -1591,7 +1590,7 @@ mptctl_eventreport (unsigned long arg) maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS); - max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents; + max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents; /* If fewer than 1 event is requested, there must have * been some type of error. diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 05789e5..4fee6be 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -2489,7 +2489,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR int idx; MPT_ADAPTER *ioc = hd->ioc; - idx = ioc->eventContext % ioc->eventLogSize; + idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; ioc->events[idx].eventContext = ioc->eventContext; -- cgit v0.10.2 From 5f07e2499d629045f7f8a60a5b442792f08732cb Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:44 -0700 Subject: [SCSI] fusion - mptctl -sense width fix Bug fix for correctly setting sense width for the MPTCOMMAND ioctl. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b603fb8..be5fcd8 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1839,7 +1839,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) goto done_free_mem; } - pScsiReq->MsgFlags = mpt_msg_flags(); + pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; + pScsiReq->MsgFlags |= mpt_msg_flags(); + /* verify that app has not requested * more sense data than driver @@ -1921,7 +1923,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) int scsidir = MPI_SCSIIO_CONTROL_READ; int dataSize; - pScsiReq->MsgFlags = mpt_msg_flags(); + pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; + pScsiReq->MsgFlags |= mpt_msg_flags(); + /* verify that app has not requested * more sense data than driver -- cgit v0.10.2 From 592f9c2fc9725b922ba8c4b1d67318ea4a301b59 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:47 -0700 Subject: [SCSI] fusion - mptctl - backplane istwi fix Moving the toolbox call from mptbase.c, over to mptctl.c, and using the mptctl infastructure to issue the call. The existing code is hanging on certain HP platforms when this ioctl is issued, and this patch fix's that. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index a3751d8..642a61b 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -452,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) } else if (func == MPI_FUNCTION_EVENT_ACK) { dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", ioc->name)); - } else if (func == MPI_FUNCTION_CONFIG || - func == MPI_FUNCTION_TOOLBOX) { + } else if (func == MPI_FUNCTION_CONFIG) { CONFIGPARMS *pCfg; unsigned long flags; @@ -5327,115 +5326,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - * mpt_toolbox - Generic function to issue toolbox message - * @ioc - Pointer to an adapter structure - * @cfg - Pointer to a toolbox structure. Struct contains - * action, page address, direction, physical address - * and pointer to a configuration page header - * Page header is updated. - * - * Returns 0 for success - * -EPERM if not allowed due to ISR context - * -EAGAIN if no msg frames currently available - * -EFAULT for non-successful reply or no reply (timeout) - */ -int -mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) -{ - ToolboxIstwiReadWriteRequest_t *pReq; - MPT_FRAME_HDR *mf; - struct pci_dev *pdev; - unsigned long flags; - int rc; - u32 flagsLength; - int in_isr; - - /* Prevent calling wait_event() (below), if caller happens - * to be in ISR context, because that is fatal! - */ - in_isr = in_interrupt(); - if (in_isr) { - dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n", - ioc->name)); - return -EPERM; - } - - /* Get and Populate a free Frame - */ - if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { - dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n", - ioc->name)); - return -EAGAIN; - } - pReq = (ToolboxIstwiReadWriteRequest_t *)mf; - pReq->Tool = pCfg->action; - pReq->Reserved = 0; - pReq->ChainOffset = 0; - pReq->Function = MPI_FUNCTION_TOOLBOX; - pReq->Reserved1 = 0; - pReq->Reserved2 = 0; - pReq->MsgFlags = 0; - pReq->Flags = pCfg->dir; - pReq->BusNum = 0; - pReq->Reserved3 = 0; - pReq->NumAddressBytes = 0x01; - pReq->Reserved4 = 0; - pReq->DataLength = cpu_to_le16(0x04); - pdev = ioc->pcidev; - if (pdev->devfn & 1) - pReq->DeviceAddr = 0xB2; - else - pReq->DeviceAddr = 0xB0; - pReq->Addr1 = 0; - pReq->Addr2 = 0; - pReq->Addr3 = 0; - pReq->Reserved5 = 0; - - /* Add a SGE to the config request. - */ - - flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4; - - mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr); - - dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n", - ioc->name, pReq->Tool)); - - /* Append pCfg pointer to end of mf - */ - *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg; - - /* Initalize the timer - */ - init_timer(&pCfg->timer); - pCfg->timer.data = (unsigned long) ioc; - pCfg->timer.function = mpt_timer_expired; - pCfg->wait_done = 0; - - /* Set the timer; ensure 10 second minimum */ - if (pCfg->timeout < 10) - pCfg->timer.expires = jiffies + HZ*10; - else - pCfg->timer.expires = jiffies + HZ*pCfg->timeout; - - /* Add to end of Q, set timer and then issue this command */ - spin_lock_irqsave(&ioc->FreeQlock, flags); - list_add_tail(&pCfg->linkage, &ioc->configQ); - spin_unlock_irqrestore(&ioc->FreeQlock, flags); - - add_timer(&pCfg->timer); - mpt_put_msg_frame(mpt_base_index, ioc, mf); - wait_event(mpt_waitq, pCfg->wait_done); - - /* mf has been freed - do not access */ - - rc = pCfg->status; - - return rc; -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mpt_timer_expired - Call back for timer process. * Used only internal config functionality. @@ -6540,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index); EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_config); -EXPORT_SYMBOL(mpt_toolbox); EXPORT_SYMBOL(mpt_findImVolumes); EXPORT_SYMBOL(mpt_read_ioc_pg_3); EXPORT_SYMBOL(mpt_alloc_fw_memory); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index ea2649e..2e53773 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -1026,7 +1026,6 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); -extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); extern int mpt_findImVolumes(MPT_ADAPTER *ioc); diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index be5fcd8..2df3b87 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -2271,13 +2271,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) hp_host_info_t __user *uarg = (void __user *) arg; MPT_ADAPTER *ioc; struct pci_dev *pdev; - char *pbuf; + char *pbuf=NULL; dma_addr_t buf_dma; hp_host_info_t karg; CONFIGPARMS cfg; ConfigPageHeader_t hdr; int iocnum; int rc, cim_rev; + ToolboxIstwiReadWriteRequest_t *IstwiRWRequest; + MPT_FRAME_HDR *mf = NULL; + MPIHeader_t *mpi_hdr; dctlprintk((": mptctl_hp_hostinfo called.\n")); /* Reset long to int. Should affect IA64 and SPARC only @@ -2413,20 +2416,67 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) } } - cfg.pageAddr = 0; - cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; - cfg.dir = MPI_TB_ISTWI_FLAGS_READ; - cfg.timeout = 10; + /* + * Gather ISTWI(Industry Standard Two Wire Interface) Data + */ + if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { + dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n", + ioc->name,__FUNCTION__)); + goto out; + } + + IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf; + mpi_hdr = (MPIHeader_t *) mf; + memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t)); + IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX; + IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; + IstwiRWRequest->MsgContext = mpi_hdr->MsgContext; + IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ; + IstwiRWRequest->NumAddressBytes = 0x01; + IstwiRWRequest->DataLength = cpu_to_le16(0x04); + if (pdev->devfn & 1) + IstwiRWRequest->DeviceAddr = 0xB2; + else + IstwiRWRequest->DeviceAddr = 0xB0; + pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); - if (pbuf) { - cfg.physAddr = buf_dma; - if ((mpt_toolbox(ioc, &cfg)) == 0) { - karg.rsvd = *(u32 *)pbuf; - } - pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); - pbuf = NULL; + if (!pbuf) + goto out; + mpt_add_sge((char *)&IstwiRWRequest->SGL, + (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma); + + ioc->ioctl->wait_done = 0; + mpt_put_msg_frame(mptctl_id, ioc, mf); + + rc = wait_event_timeout(mptctl_wait, + ioc->ioctl->wait_done == 1, + HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */); + + if(rc <=0 && (ioc->ioctl->wait_done != 1 )) { + /* + * Now we need to reset the board + */ + mpt_free_msg_frame(ioc, mf); + mptctl_timeout_expired(ioc->ioctl); + goto out; } + /* + *ISTWI Data Definition + * pbuf[0] = FW_VERSION = 0x4 + * pbuf[1] = Bay Count = 6 or 4 or 2, depending on + * the config, you should be seeing one out of these three values + * pbuf[2] = Drive Installed Map = bit pattern depend on which + * bays have drives in them + * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3) + */ + if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) + karg.rsvd = *(u32 *)pbuf; + + out: + if (pbuf) + pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); + /* Copy the data from kernel memory to user memory */ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { -- cgit v0.10.2 From 946cbf040adb9db05bb895a4b629537fd2d03b0e Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:50 -0700 Subject: [SCSI] fusion - mptctl -firmware download fix Fix's firmware download ioctl to work with SAS. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 2df3b87..fe10cc0 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -674,22 +674,23 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) u16 iocstat; pFWDownloadReply_t ReplyMsg = NULL; - dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); + dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); - dctlprintk((KERN_INFO "DbG: kfwdl.bufp = %p\n", ufwbuf)); - dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen)); - dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc)); + dctlprintk(("DbG: kfwdl.bufp = %p\n", ufwbuf)); + dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen)); + dctlprintk(("DbG: kfwdl.ioc = %04xh\n", ioc)); - if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) { - dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n", - __FILE__, __LINE__, ioc)); + if (mpt_verify_adapter(ioc, &iocp) < 0) { + dctlprintk(("ioctl_fwdl - ioc%d not found!\n", + ioc)); return -ENODEV; /* (-6) No such device or address */ - } + } else { - /* Valid device. Get a message frame and construct the FW download message. - */ - if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) - return -EAGAIN; + /* Valid device. Get a message frame and construct the FW download message. + */ + if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) + return -EAGAIN; + } dlmsg = (FWDownload_t*) mf; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; sgOut = (char *) (ptsge + 1); @@ -702,7 +703,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) dlmsg->ChainOffset = 0; dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD; dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0; - dlmsg->MsgFlags = 0; + if (iocp->facts.MsgVersion >= MPI_VERSION_01_05) + dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT; + else + dlmsg->MsgFlags = 0; + /* Set up the Transaction SGE. */ @@ -754,7 +759,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) goto fwdl_out; } - dctlprintk((KERN_INFO "DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); + dctlprintk(("DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); /* * Parse SG list, copying sgl itself, @@ -803,7 +808,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) /* * Finally, perform firmware download. */ - iocp->ioctl->wait_done = 0; + ReplyMsg = NULL; mpt_put_msg_frame(mptctl_id, iocp, mf); /* Now wait for the command to complete */ -- cgit v0.10.2 From ea5a7a82f9d2d8a81f8fa541c34a12b43d390f61 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:20:01 -0700 Subject: [SCSI] fusion - mptctl -adding asyn event notification support Adding aen support. Signed-off-by: Eric Moore Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 2e53773..723d543 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -616,6 +616,7 @@ typedef struct _MPT_ADAPTER * increments by 32 bytes */ int errata_flag_1064; + int aen_event_read_flag; /* flag to indicate event log was read*/ u8 FirstWhoInit; u8 upload_fw; /* If set, do a fw upload */ u8 reload_fw; /* Force a FW Reload on next reset */ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index fe10cc0..9b64e07 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -136,6 +136,12 @@ static void mptctl_free_tm_flags(MPT_ADAPTER *ioc); */ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); +/* + * Event Handler function + */ +static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); +struct fasync_struct *async_queue=NULL; + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Scatter gather list (SGL) sizes and limits... @@ -472,6 +478,69 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* ASYNC Event Notification Support */ +static int +mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) +{ + u8 event; + + event = le32_to_cpu(pEvReply->Event) & 0xFF; + + dctlprintk(("%s() called\n", __FUNCTION__)); + if(async_queue == NULL) + return 1; + + /* Raise SIGIO for persistent events. + * TODO - this define is not in MPI spec yet, + * but they plan to set it to 0x21 + */ + if (event == 0x21 ) { + ioc->aen_event_read_flag=1; + dctlprintk(("Raised SIGIO to application\n")); + devtprintk(("Raised SIGIO to application\n")); + kill_fasync(&async_queue, SIGIO, POLL_IN); + return 1; + } + + /* This flag is set after SIGIO was raised, and + * remains set until the application has read + * the event log via ioctl=MPTEVENTREPORT + */ + if(ioc->aen_event_read_flag) + return 1; + + /* Signal only for the events that are + * requested for by the application + */ + if (ioc->events && (ioc->eventTypes & ( 1 << event))) { + ioc->aen_event_read_flag=1; + dctlprintk(("Raised SIGIO to application\n")); + devtprintk(("Raised SIGIO to application\n")); + kill_fasync(&async_queue, SIGIO, POLL_IN); + } + return 1; +} + +static int +mptctl_fasync(int fd, struct file *filep, int mode) +{ + MPT_ADAPTER *ioc; + + list_for_each_entry(ioc, &ioc_list, list) + ioc->aen_event_read_flag=0; + + dctlprintk(("%s() called\n", __FUNCTION__)); + return fasync_helper(fd, filep, mode, &async_queue); +} + +static int +mptctl_release(struct inode *inode, struct file *filep) +{ + dctlprintk(("%s() called\n", __FUNCTION__)); + return fasync_helper(-1, filep, 0, &async_queue); +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * MPT ioctl handler * cmd - specify the particular IOCTL command to be issued @@ -1603,6 +1672,9 @@ mptctl_eventreport (unsigned long arg) if ((max < 1) || !ioc->events) return -ENODATA; + /* reset this flag so SIGIO can restart */ + ioc->aen_event_read_flag=0; + /* Copy the data from kernel memory to user memory */ numBytes = max * sizeof(MPT_IOCTL_EVENTS); @@ -2649,6 +2721,8 @@ mptctl_hp_targetinfo(unsigned long arg) static struct file_operations mptctl_fops = { .owner = THIS_MODULE, .llseek = no_llseek, + .release = mptctl_release, + .fasync = mptctl_fasync, .unlocked_ioctl = mptctl_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_mpctl_ioctl, @@ -2893,6 +2967,11 @@ static int __init mptctl_init(void) /* FIXME! */ } + if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) { + devtprintk((KERN_INFO MYNAM + ": Registered for IOC event notifications\n")); + } + return 0; out_fail: -- cgit v0.10.2 From 122da30223c06cee181044af6d32e88b256d10df Mon Sep 17 00:00:00 2001 From: Joshua Giles Date: Fri, 3 Feb 2006 15:34:17 -0800 Subject: [SCSI] megaraid_sas: register 16 byte CDB capability This patch properly registers the 16 byte command length capability of the megaraid_sas controlled hardware with the scsi midlayer. All megaraid_sas hardware supports 16 byte CDB's. Signed-off-by: Joshua Giles Signed-off-by: Sumant Patro Signed-off-by: James Bottomley diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index f8c16cb..9e8085b 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,3 +1,15 @@ +1 Release Date : Fri Feb 03 14:16:25 PST 2006 - Sumant Patro + +2 Current Version : 00.00.02.04 +3 Older Version : 00.00.02.02 +i. Register 16 byte CDB capability with scsi midlayer + + "Ths patch properly registers the 16 byte command length capability of the + megaraid_sas controlled hardware with the scsi midlayer. All megaraid_sas + hardware supports 16 byte CDB's." + + -Joshua Giles + 1 Release Date : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro 2 Current Version : 00.00.02.02 3 Older Version : 00.00.02.01 diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index a487f41..0b73824 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.02.02 + * Version : v00.00.02.04 * * Authors: * Sreenivas Bagalkote @@ -1983,6 +1983,7 @@ static int megasas_io_attach(struct megasas_instance *instance) host->max_channel = MEGASAS_MAX_CHANNELS - 1; host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; host->max_lun = MEGASAS_MAX_LUN; + host->max_cmd_len = 16; /* * Notify the mid-layer about the new controller diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index d6d166c..917326f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -18,9 +18,9 @@ /** * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.02.02" -#define MEGASAS_RELDATE "Jan 23, 2006" -#define MEGASAS_EXT_VERSION "Mon Jan 23 14:09:01 PST 2006" +#define MEGASAS_VERSION "00.00.02.04" +#define MEGASAS_RELDATE "Feb 03, 2006" +#define MEGASAS_EXT_VERSION "Fri Feb 03 14:16:25 PST 2006" /* * ===================================== * MegaRAID SAS MFI firmware definitions -- cgit v0.10.2 From f9876f0b67c3f0b04ee2167602df54e7ae139ad7 Mon Sep 17 00:00:00 2001 From: Sumant Patro Date: Fri, 3 Feb 2006 15:34:35 -0800 Subject: [SCSI] megaraid_sas: support for 1078 type controller added This patch adds support for 1078 type controller (device id : 0x60). Signed-off-by: Sumant Patro Signed-off-by: James Bottomley diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index 9e8085b..2dafa63 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,3 +1,14 @@ +1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro +2 Current Version : 00.00.02.04 +3 Older Version : 00.00.02.04 + +i. Support for 1078 type (ppc IOP) controller, device id : 0x60 added. + During initialization, depending on the device id, the template members + are initialized with function pointers specific to the ppc or + xscale controllers. + + -Sumant Patro + 1 Release Date : Fri Feb 03 14:16:25 PST 2006 - Sumant Patro 2 Current Version : 00.00.02.04 diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 0b73824..7de267e 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -60,6 +60,12 @@ static struct pci_device_id megasas_pci_table[] = { PCI_ANY_ID, }, { + PCI_VENDOR_ID_LSI_LOGIC, + PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP + PCI_ANY_ID, + PCI_ANY_ID, + }, + { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5, // xscale IOP PCI_ANY_ID, @@ -199,6 +205,86 @@ static struct megasas_instance_template megasas_instance_template_xscale = { */ /** +* The following functions are defined for ppc (deviceid : 0x60) +* controllers +*/ + +/** + * megasas_enable_intr_ppc - Enables interrupts + * @regs: MFI register set + */ +static inline void +megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) +{ + writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); + + writel(~0x80000004, &(regs)->outbound_intr_mask); + + /* Dummy readl to force pci flush */ + readl(®s->outbound_intr_mask); +} + +/** + * megasas_read_fw_status_reg_ppc - returns the current FW status value + * @regs: MFI register set + */ +static u32 +megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs) +{ + return readl(&(regs)->outbound_scratch_pad); +} + +/** + * megasas_clear_interrupt_ppc - Check & clear interrupt + * @regs: MFI register set + */ +static int +megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) +{ + u32 status; + /* + * Check if it is our interrupt + */ + status = readl(®s->outbound_intr_status); + + if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) { + return 1; + } + + /* + * Clear the interrupt by writing back the same value + */ + writel(status, ®s->outbound_doorbell_clear); + + return 0; +} +/** + * megasas_fire_cmd_ppc - Sends command to the FW + * @frame_phys_addr : Physical address of cmd + * @frame_count : Number of frames for the command + * @regs : MFI register set + */ +static inline void +megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs) +{ + writel((frame_phys_addr | (frame_count<<1))|1, + &(regs)->inbound_queue_port); +} + +static struct megasas_instance_template megasas_instance_template_ppc = { + + .fire_cmd = megasas_fire_cmd_ppc, + .enable_intr = megasas_enable_intr_ppc, + .clear_intr = megasas_clear_intr_ppc, + .read_fw_status_reg = megasas_read_fw_status_reg_ppc, +}; + +/** +* This is the end of set of functions & definitions +* specific to ppc (deviceid : 0x60) controllers +*/ + +/** * megasas_disable_intr - Disables interrupts * @regs: MFI register set */ @@ -1607,7 +1693,17 @@ static int megasas_init_mfi(struct megasas_instance *instance) reg_set = instance->reg_set; - instance->instancet = &megasas_instance_template_xscale; + switch(instance->pdev->device) + { + case PCI_DEVICE_ID_LSI_SAS1078R: + instance->instancet = &megasas_instance_template_ppc; + break; + case PCI_DEVICE_ID_LSI_SAS1064R: + case PCI_DEVICE_ID_DELL_PERC5: + default: + instance->instancet = &megasas_instance_template_xscale; + break; + } /* * We expect the FW state to be READY diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 917326f..89639f0 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -20,7 +20,7 @@ */ #define MEGASAS_VERSION "00.00.02.04" #define MEGASAS_RELDATE "Feb 03, 2006" -#define MEGASAS_EXT_VERSION "Fri Feb 03 14:16:25 PST 2006" +#define MEGASAS_EXT_VERSION "Fri Feb 03 14:31:44 PST 2006" /* * ===================================== * MegaRAID SAS MFI firmware definitions @@ -553,31 +553,46 @@ struct megasas_ctrl_info { #define MFI_OB_INTR_STATUS_MASK 0x00000002 #define MFI_POLL_TIMEOUT_SECS 10 +#define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 +#define PCI_DEVICE_ID_LSI_SAS1078R 0x00000060 + struct megasas_register_set { + u32 reserved_0[4]; /*0000h*/ - u32 reserved_0[4]; /*0000h */ + u32 inbound_msg_0; /*0010h*/ + u32 inbound_msg_1; /*0014h*/ + u32 outbound_msg_0; /*0018h*/ + u32 outbound_msg_1; /*001Ch*/ - u32 inbound_msg_0; /*0010h */ - u32 inbound_msg_1; /*0014h */ - u32 outbound_msg_0; /*0018h */ - u32 outbound_msg_1; /*001Ch */ + u32 inbound_doorbell; /*0020h*/ + u32 inbound_intr_status; /*0024h*/ + u32 inbound_intr_mask; /*0028h*/ - u32 inbound_doorbell; /*0020h */ - u32 inbound_intr_status; /*0024h */ - u32 inbound_intr_mask; /*0028h */ + u32 outbound_doorbell; /*002Ch*/ + u32 outbound_intr_status; /*0030h*/ + u32 outbound_intr_mask; /*0034h*/ - u32 outbound_doorbell; /*002Ch */ - u32 outbound_intr_status; /*0030h */ - u32 outbound_intr_mask; /*0034h */ + u32 reserved_1[2]; /*0038h*/ - u32 reserved_1[2]; /*0038h */ + u32 inbound_queue_port; /*0040h*/ + u32 outbound_queue_port; /*0044h*/ - u32 inbound_queue_port; /*0040h */ - u32 outbound_queue_port; /*0044h */ + u32 reserved_2[22]; /*0048h*/ - u32 reserved_2; /*004Ch */ + u32 outbound_doorbell_clear; /*00A0h*/ - u32 index_registers[1004]; /*0050h */ + u32 reserved_3[3]; /*00A4h*/ + + u32 outbound_scratch_pad ; /*00B0h*/ + + u32 reserved_4[3]; /*00B4h*/ + + u32 inbound_low_queue_port ; /*00C0h*/ + + u32 inbound_high_queue_port ; /*00C4h*/ + + u32 reserved_5; /*00C8h*/ + u32 index_registers[820]; /*00CCh*/ } __attribute__ ((packed)); -- cgit v0.10.2 From 40cdc840dc337cb17d81bcf028b40834e78c1038 Mon Sep 17 00:00:00 2001 From: Jenx Axboe Date: Sun, 5 Feb 2006 16:36:23 +0100 Subject: [SCSI] gdth: don't map zero-length requests Don't map zero-length requests in gdth, zome architectures don't like that in their dma mapping routines. [ I'm pretty sure Jens posted this before, but for some reason it got forgotten --hch ] Signed-off-by: James Bottomley diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index bd3ffdf..62e3cda 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -2816,7 +2816,7 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) } #endif - } else { + } else if (scp->request_bufflen) { scp->SCp.Status = GDTH_MAP_SINGLE; scp->SCp.Message = (read_write == 1 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); -- cgit v0.10.2 From 62288f105b3cad0b8643526d2a41b5503d0a1476 Mon Sep 17 00:00:00 2001 From: adam radford Date: Sun, 5 Feb 2006 14:51:43 -0800 Subject: [SCSI] 3ware 9000 driver >4GB memory fix The attached patch fixes a bug in the 3ware 9000 series driver: - Fix use_sg == 0 mapping on systems with 4GB or higher. This fixes REPORT_LUNS (0xa0) failing with 3ware 9000 controllers on systems with lots of ram, mentioned in bugzilla # 6009: http://bugzilla.kernel.org/show_bug.cgi?id=6009 Signed-off-by: Adam Radford Signed-off-by: James Bottomley diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 31c4975..d9152d0 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -61,6 +61,7 @@ Add support for embedded firmware error strings. 2.26.02.003 - Correctly handle single sgl's with use_sg=1. 2.26.02.004 - Add support for 9550SX controllers. + 2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher. */ #include @@ -84,7 +85,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.004" +#define TW_DRIVER_VERSION "2.26.02.005" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -1408,7 +1409,7 @@ static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int requ dma_addr_t mapping; struct scsi_cmnd *cmd = tw_dev->srb[request_id]; struct pci_dev *pdev = tw_dev->tw_pci_dev; - int retval = 0; + dma_addr_t retval = 0; if (cmd->request_bufflen == 0) { retval = 0; @@ -1798,7 +1799,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, int i, sg_count; struct scsi_cmnd *srb = NULL; struct scatterlist *sglist = NULL; - u32 buffaddr = 0x0; + dma_addr_t buffaddr = 0x0; int retval = 1; if (tw_dev->srb[request_id]) { -- cgit v0.10.2 From 387f96b4d9391bf3ce6928fb9cd90c9c7df37291 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 7 Feb 2006 08:45:45 -0800 Subject: [PATCH] qla2xxx: Close window on race between rport removal and fcport transition. Fcport visibility is recognized during interrupt time, but, rport removal can only occur during a process (sleeping)-context. Return a DID_IMM_RETRY status for commands submitted within this window to insure I/Os do not prematurely run-out of retries. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 495ccbc..9b5a10a 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -366,6 +366,12 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) goto qc_fail_command; } + /* Close window on fcport/rport state-transitioning. */ + if (!*(fc_port_t **)rport->dd_data) { + cmd->result = DID_IMM_RETRY << 16; + goto qc_fail_command; + } + if (atomic_read(&fcport->state) != FCS_ONLINE) { if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || atomic_read(&ha->loop_state) == LOOP_DEAD) { @@ -421,6 +427,12 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) goto qc24_fail_command; } + /* Close window on fcport/rport state-transitioning. */ + if (!*(fc_port_t **)rport->dd_data) { + cmd->result = DID_IMM_RETRY << 16; + goto qc24_fail_command; + } + if (atomic_read(&fcport->state) != FCS_ONLINE) { if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || atomic_read(&ha->loop_state) == LOOP_DEAD) { @@ -1675,11 +1687,13 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, spin_lock_irqsave(&fcport->rport_lock, flags); fcport->drport = rport; fcport->rport = NULL; + *(fc_port_t **)rport->dd_data = NULL; spin_unlock_irqrestore(&fcport->rport_lock, flags); set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); } else { spin_lock_irqsave(&fcport->rport_lock, flags); fcport->rport = NULL; + *(fc_port_t **)rport->dd_data = NULL; spin_unlock_irqrestore(&fcport->rport_lock, flags); fc_remote_port_delete(rport); } -- cgit v0.10.2 From f7757a5f0fa94a0ce4d6ea55f440845bb3faf712 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 7 Feb 2006 08:45:30 -0800 Subject: [PATCH] qla2xxx: Remove bogus debug-code. Commit 854165f4245c4a3b4a8cc363ba2050033151e196 inadvertently added some code meant only for testing -- the driver was ignoring the non-zero function numbers of a multi-port HBA. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 9b5a10a..9f91f1a 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1283,9 +1283,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) fc_port_t *fcport; struct scsi_host_template *sht; -if (PCI_FUNC(pdev->devfn)) - goto probe_out; - if (pci_enable_device(pdev)) goto probe_out; -- cgit v0.10.2 From 247ec457ce108000987be517c83868f6361d9f76 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 7 Feb 2006 08:45:40 -0800 Subject: [PATCH] qla2xxx: Pass input-buffer length to Get-ID-List mailbox command. Recent ISP24xx firmwares require that mailbox register 8 be set to the maximum number of bytes to transfer during DMA copying of the list. We safely set this value to zero (infinite), since the call is *only* made in FCAL topologies. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 49ce197..363dfdd 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -1873,7 +1873,8 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, mcp->mb[3] = LSW(id_list_dma); mcp->mb[6] = MSW(MSD(id_list_dma)); mcp->mb[7] = LSW(MSD(id_list_dma)); - mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2; + mcp->mb[8] = 0; + mcp->out_mb |= MBX_8|MBX_7|MBX_6|MBX_3|MBX_2; } else { mcp->mb[1] = MSW(id_list_dma); mcp->mb[2] = LSW(id_list_dma); -- cgit v0.10.2 From 0d4be1240b2668b6a3ffadb15eb660baf52f8377 Mon Sep 17 00:00:00 2001 From: "andrew.vasquez@qlogic.com" Date: Tue, 7 Feb 2006 08:45:35 -0800 Subject: [PATCH] qla2xxx: Correct lun assignment during IOCB submission. 4gb products require an IOCB's FCP-LUN to be formatted in wire-format prior to submission. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 7ec0b8d..6544b6d 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -814,6 +814,7 @@ qla24xx_start_scsi(srb_t *sp) cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); + host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); /* Load SCSI command packet. */ memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); -- cgit v0.10.2 From 479a079663bd4c5f3d2714643b1b8c406aaba3e0 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 7 Feb 2006 16:37:08 -0800 Subject: IPoIB: Don't start send-only joins while multicast thread is stopped Fix the following race scenario: - Device is up. - Port event or set mcast list triggers ipoib_mcast_stop_thread, this cancels the query and waits on mcast "done" completion. - Completion is called and "done" is set. - Meanwhile, ipoib_mcast_send arrives and starts a new query, re-initializing "done". Fix this by adding a "multicast started" bit and checking it before starting a send-only join. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index e0a5412..2f85a9a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -78,6 +78,7 @@ enum { IPOIB_FLAG_SUBINTERFACE = 4, IPOIB_MCAST_RUN = 5, IPOIB_STOP_REAPER = 6, + IPOIB_MCAST_STARTED = 7, IPOIB_MAX_BACKOFF_SECONDS = 16, diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ccaa0c3..1c71482 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -601,6 +601,10 @@ int ipoib_mcast_start_thread(struct net_device *dev) queue_work(ipoib_workqueue, &priv->mcast_task); mutex_unlock(&mcast_mutex); + spin_lock_irq(&priv->lock); + set_bit(IPOIB_MCAST_STARTED, &priv->flags); + spin_unlock_irq(&priv->lock); + return 0; } @@ -611,6 +615,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) ipoib_dbg_mcast(priv, "stopping multicast thread\n"); + spin_lock_irq(&priv->lock); + clear_bit(IPOIB_MCAST_STARTED, &priv->flags); + spin_unlock_irq(&priv->lock); + mutex_lock(&mcast_mutex); clear_bit(IPOIB_MCAST_RUN, &priv->flags); cancel_delayed_work(&priv->mcast_task); @@ -693,6 +701,12 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, */ spin_lock(&priv->lock); + if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags)) { + ++priv->stats.tx_dropped; + dev_kfree_skb_any(skb); + goto unlock; + } + mcast = __ipoib_mcast_find(dev, mgid); if (!mcast) { /* Let's create a new send only group now */ @@ -754,6 +768,7 @@ out: ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); } +unlock: spin_unlock(&priv->lock); } -- cgit v0.10.2 From 7bcb974ef6a0ae903888272c92c66ea779388c01 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 7 Feb 2006 16:39:26 -0800 Subject: IPoIB: Fix another send-only join race Further, there's an additional issue that I saw in testing: ipoib_mcast_send may get called when priv->broadcast is NULL (e.g. if the device was downed and then upped internally because of a port event). If this happends and the send-only join request gets completed before priv->broadcast is set, we get an oops. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 1c71482..932bf13 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -701,7 +701,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, */ spin_lock(&priv->lock); - if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags)) { + if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || !priv->broadcast) { ++priv->stats.tx_dropped; dev_kfree_skb_any(skb); goto unlock; -- cgit v0.10.2 From f823bcae2b9f194cfc164b8cbb87d71695dec563 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 5 Feb 2006 20:37:53 -0700 Subject: [PARISC] Convert ccio-dma.c to use seq_file Gut ccio-dma.c of the ugly proc append and snprintf cruft and just use seq_printf instead. Tested on a K-class. Signed-off-by: Kyle McMartin diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index f46e843..93f8a8f 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include /* for L1_CACHE_BYTES */ @@ -1019,62 +1021,33 @@ static struct hppa_dma_ops ccio_ops = { }; #ifdef CONFIG_PROC_FS -static int proc_append(char *src, int len, char **dst, off_t *offset, int *max) -{ - if (len < *offset) { - *offset -= len; - return 0; - } - if (*offset > 0) { - src += *offset; - len -= *offset; - *offset = 0; - } - if (len > *max) { - len = *max; - } - memcpy(*dst, src, len); - *dst += len; - *max -= len; - return (*max == 0); -} - -static int ccio_proc_info(char *buf, char **start, off_t offset, int count, - int *eof, void *data) +static int ccio_proc_info(struct seq_file *m, void *p) { - int max = count; - char tmp[80]; /* width of an ANSI-standard terminal */ + int len = 0; struct ioc *ioc = ioc_list; while (ioc != NULL) { unsigned int total_pages = ioc->res_size << 3; unsigned long avg = 0, min, max; - int j, len; + int j; - len = sprintf(tmp, "%s\n", ioc->name); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + len += seq_printf(m, "%s\n", ioc->name); - len = sprintf(tmp, "Cujo 2.0 bug : %s\n", - (ioc->cujo20_bug ? "yes" : "no")); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + len += seq_printf(m, "Cujo 2.0 bug : %s\n", + (ioc->cujo20_bug ? "yes" : "no")); - len = sprintf(tmp, "IO PDIR size : %d bytes (%d entries)\n", - total_pages * 8, total_pages); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n", + total_pages * 8, total_pages); + #ifdef CCIO_MAP_STATS - len = sprintf(tmp, "IO PDIR entries : %ld free %ld used (%d%%)\n", - total_pages - ioc->used_pages, ioc->used_pages, - (int)(ioc->used_pages * 100 / total_pages)); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n", + total_pages - ioc->used_pages, ioc->used_pages, + (int)(ioc->used_pages * 100 / total_pages)); #endif - len = sprintf(tmp, "Resource bitmap : %d bytes (%d pages)\n", - ioc->res_size, total_pages); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + + len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", + ioc->res_size, total_pages); + #ifdef CCIO_SEARCH_TIME min = max = ioc->avg_search[0]; for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) { @@ -1085,70 +1058,83 @@ static int ccio_proc_info(char *buf, char **start, off_t offset, int count, min = ioc->avg_search[j]; } avg /= CCIO_SEARCH_SAMPLE; - len = sprintf(tmp, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", - min, avg, max); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", + min, avg, max); #endif #ifdef CCIO_MAP_STATS - len = sprintf(tmp, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", - ioc->msingle_calls, ioc->msingle_pages, - (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; - + len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", + ioc->msingle_calls, ioc->msingle_pages, + (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); /* KLUGE - unmap_sg calls unmap_single for each mapped page */ min = ioc->usingle_calls - ioc->usg_calls; max = ioc->usingle_pages - ioc->usg_pages; - len = sprintf(tmp, "pci_unmap_single: %8ld calls %8ld pages (avg %d/1000)\n", - min, max, (int)((max * 1000)/min)); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + len += seq_printf(m, "pci_unmap_single: %8ld calls %8ld pages (avg %d/1000)\n", + min, max, (int)((max * 1000)/min)); - len = sprintf(tmp, "pci_map_sg() : %8ld calls %8ld pages (avg %d/1000)\n", - ioc->msg_calls, ioc->msg_pages, - (int)((ioc->msg_pages * 1000)/ioc->msg_calls)); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; - len = sprintf(tmp, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n", - ioc->usg_calls, ioc->usg_pages, - (int)((ioc->usg_pages * 1000)/ioc->usg_calls)); - if (proc_append(tmp, len, &buf, &offset, &count)) - break; + len += seq_printf(m, "pci_map_sg() : %8ld calls %8ld pages (avg %d/1000)\n", + ioc->msg_calls, ioc->msg_pages, + (int)((ioc->msg_pages * 1000)/ioc->msg_calls)); + + len += seq_printf(m, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n", + ioc->usg_calls, ioc->usg_pages, + (int)((ioc->usg_pages * 1000)/ioc->usg_calls)); #endif /* CCIO_MAP_STATS */ + ioc = ioc->next; } - if (count == 0) { - *eof = 1; - } - return (max - count); + return 0; +} + +static int ccio_proc_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, &ccio_proc_info, NULL); } -static int ccio_resource_map(char *buf, char **start, off_t offset, int len, - int *eof, void *data) +static struct file_operations ccio_proc_info_fops = { + .owner = THIS_MODULE, + .open = ccio_proc_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int ccio_proc_bitmap_info(struct seq_file *m, void *p) { + int len = 0; struct ioc *ioc = ioc_list; - buf[0] = '\0'; while (ioc != NULL) { u32 *res_ptr = (u32 *)ioc->res_map; int j; for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) { if ((j & 7) == 0) - strcat(buf,"\n "); - sprintf(buf, "%s %08x", buf, *res_ptr); + len += seq_puts(m, "\n "); + len += seq_printf(m, "%08x", *res_ptr); res_ptr++; } - strcat(buf, "\n\n"); + len += seq_puts(m, "\n\n"); ioc = ioc->next; break; /* XXX - remove me */ } - return strlen(buf); + return 0; } + +static int ccio_proc_bitmap_open(struct inode *inode, struct file *file) +{ + return single_open(file, &ccio_proc_bitmap_info, NULL); +} + +static struct file_operations ccio_proc_bitmap_fops = { + .owner = THIS_MODULE, + .open = ccio_proc_bitmap_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /** @@ -1556,6 +1542,7 @@ static int ccio_probe(struct parisc_device *dev) { int i; struct ioc *ioc, **ioc_p = &ioc_list; + struct proc_dir_entry *info_entry, *bitmap_entry; ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL); if (ioc == NULL) { @@ -1583,13 +1570,14 @@ static int ccio_probe(struct parisc_device *dev) BUG_ON(dev->dev.platform_data == NULL); HBA_DATA(dev->dev.platform_data)->iommu = ioc; - if (ioc_count == 0) { - /* FIXME: Create separate entries for each ioc */ - create_proc_read_entry(MODULE_NAME, S_IRWXU, proc_runway_root, - ccio_proc_info, NULL); - create_proc_read_entry(MODULE_NAME"-bitmap", S_IRWXU, - proc_runway_root, ccio_resource_map, NULL); + info_entry = create_proc_entry(MODULE_NAME, 0, proc_runway_root); + if (info_entry) + info_entry->proc_fops = &ccio_proc_info_fops; + + bitmap_entry = create_proc_entry(MODULE_NAME"-bitmap", 0, proc_runway_root); + if (bitmap_entry) + bitmap_entry->proc_fops = &ccio_proc_bitmap_fops; } ioc_count++; -- cgit v0.10.2 From 7ec14e49b72da20d7212c707f226271525aee4ae Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Mon, 6 Feb 2006 10:10:15 -0700 Subject: [PARISC] Convert sba_iommu.c to use seq_file Use seq_file interface for proc output in sba_iommu. Also clean up the bus root assignment, and give the proc files a more logical name. Tested on my J6000. Signed-off-by: Kyle McMartin diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 52f265e..5d47c59 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -37,6 +37,8 @@ #include /* for register_parisc_driver() stuff */ #include +#include + #include /* for proc_runway_root */ #include /* for PDC_MODEL_* */ #include /* for is_pdc_pat() */ @@ -1892,46 +1894,43 @@ sba_common_init(struct sba_device *sba_dev) } #ifdef CONFIG_PROC_FS -static int sba_proc_info(char *buf, char **start, off_t offset, int len) +static int sba_proc_info(struct seq_file *m, void *p) { struct sba_device *sba_dev = sba_list; struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ - unsigned long i; #ifdef SBA_COLLECT_STATS unsigned long avg = 0, min, max; #endif + int i, len = 0; - sprintf(buf, "%s rev %d.%d\n", + len += seq_printf(m, "%s rev %d.%d\n", sba_dev->name, (sba_dev->hw_rev & 0x7) + 1, (sba_dev->hw_rev & 0x18) >> 3 ); - sprintf(buf, "%sIO PDIR size : %d bytes (%d entries)\n", - buf, + len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n", (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ total_pages); - sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", - buf, ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ + len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", + ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ - sprintf(buf, "%sLMMIO_BASE/MASK/ROUTE %08x %08x %08x\n", - buf, + len += seq_printf(m, "LMMIO_BASE/MASK/ROUTE %08x %08x %08x\n", READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_BASE), READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_MASK), READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_ROUTE) ); for (i=0; i<4; i++) - sprintf(buf, "%sDIR%ld_BASE/MASK/ROUTE %08x %08x %08x\n", - buf, i, + len += seq_printf(m, "DIR%d_BASE/MASK/ROUTE %08x %08x %08x\n", i, READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_BASE + i*0x18), READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_MASK + i*0x18), READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_ROUTE + i*0x18) ); #ifdef SBA_COLLECT_STATS - sprintf(buf, "%sIO PDIR entries : %ld free %ld used (%d%%)\n", buf, + len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n", total_pages - ioc->used_pages, ioc->used_pages, (int) (ioc->used_pages * 100 / total_pages)); @@ -1942,53 +1941,76 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len) if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; } avg /= SBA_SEARCH_SAMPLE; - sprintf(buf, "%s Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", - buf, min, avg, max); + len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", + min, avg, max); - sprintf(buf, "%spci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->msingle_calls, ioc->msingle_pages, + len += seq_printf(m, "pci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", + ioc->msingle_calls, ioc->msingle_pages, (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); /* KLUGE - unmap_sg calls unmap_single for each mapped page */ min = ioc->usingle_calls; max = ioc->usingle_pages - ioc->usg_pages; - sprintf(buf, "%spci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", - buf, min, max, - (int) ((max * 1000)/min)); + len += seq_printf(m, "pci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", + min, max, (int) ((max * 1000)/min)); - sprintf(buf, "%spci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->msg_calls, ioc->msg_pages, + len += seq_printf(m, "pci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", + ioc->msg_calls, ioc->msg_pages, (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); - sprintf(buf, "%spci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", - buf, ioc->usg_calls, ioc->usg_pages, + len += seq_printf(m, "pci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", + ioc->usg_calls, ioc->usg_pages, (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); #endif - return strlen(buf); + return 0; } -#if 0 -/* XXX too much output - exceeds 4k limit and needs to be re-written */ static int -sba_resource_map(char *buf, char **start, off_t offset, int len) +sba_proc_open(struct inode *i, struct file *f) +{ + return single_open(f, &sba_proc_info, NULL); +} + +static struct file_operations sba_proc_fops = { + .owner = THIS_MODULE, + .open = sba_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int +sba_proc_bitmap_info(struct seq_file *m, void *p) { struct sba_device *sba_dev = sba_list; - struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Mutli-IOC suppoer! */ + struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ unsigned int *res_ptr = (unsigned int *)ioc->res_map; - int i; + int i, len = 0; - buf[0] = '\0'; - for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) { + for (i = 0; i < (ioc->res_size/sizeof(unsigned int)); ++i, ++res_ptr) { if ((i & 7) == 0) - strcat(buf,"\n "); - sprintf(buf, "%s %08x", buf, *res_ptr); + len += seq_printf(m, "\n "); + len += seq_printf(m, " %08x", *res_ptr); } - strcat(buf, "\n"); + len += seq_printf(m, "\n"); - return strlen(buf); + return 0; } -#endif /* 0 */ + +static int +sba_proc_bitmap_open(struct inode *i, struct file *f) +{ + return single_open(f, &sba_proc_bitmap_info, NULL); +} + +static struct file_operations sba_proc_bitmap_fops = { + .owner = THIS_MODULE, + .open = sba_proc_bitmap_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /* CONFIG_PROC_FS */ static struct parisc_device_id sba_tbl[] = { @@ -2021,6 +2043,7 @@ sba_driver_callback(struct parisc_device *dev) int i; char *version; void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); + struct proc_dir_entry *info_entry, *bitmap_entry, *root; sba_dump_ranges(sba_addr); @@ -2088,19 +2111,27 @@ sba_driver_callback(struct parisc_device *dev) hppa_dma_ops = &sba_ops; #ifdef CONFIG_PROC_FS - if (IS_ASTRO(&dev->id)) { - create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info); - } else if (IS_IKE(&dev->id)) { - create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info); - } else if (IS_PLUTO(&dev->id)) { - create_proc_info_entry("Pluto", 0, proc_mckinley_root, sba_proc_info); - } else { - create_proc_info_entry("Reo", 0, proc_runway_root, sba_proc_info); + switch (dev->id.hversion) { + case PLUTO_MCKINLEY_PORT: + root = proc_mckinley_root; + break; + case ASTRO_RUNWAY_PORT: + case IKE_MERCED_PORT: + default: + root = proc_runway_root; + break; } -#if 0 - create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map); -#endif + + info_entry = create_proc_entry("sba_iommu", 0, root); + bitmap_entry = create_proc_entry("sba_iommu-bitmap", 0, root); + + if (info_entry) + info_entry->proc_fops = &sba_proc_fops; + + if (bitmap_entry) + bitmap_entry->proc_fops = &sba_proc_bitmap_fops; #endif + parisc_vmerge_boundary = IOVP_SIZE; parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG; parisc_has_iommu(); -- cgit v0.10.2 From 28b2425ac76b0f043f2efd34521f2a3c7ec8ccc5 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 8 Feb 2006 23:33:15 -0500 Subject: [PARISC] Stub out pselect6/ppoll until TIF_RESTORE_SIGMASK is done Swap out pselect6/ppoll for ni_syscall for now. We also have to switch the macro to ENTRY_SAME since compat_sys_ni_syscall does not exist. Signed-off-by: Kyle McMartin diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 51d2480..66224f7 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -377,8 +377,8 @@ ENTRY_SAME(inotify_init) ENTRY_SAME(inotify_add_watch) /* 270 */ ENTRY_SAME(inotify_rm_watch) - ENTRY_COMP(pselect6) - ENTRY_COMP(ppoll) + ENTRY_SAME(ni_syscall) /* 271 ENTRY_COMP(pselect6) */ + ENTRY_SAME(ni_syscall) /* 272 ENTRY_COMP(ppoll) */ ENTRY_SAME(migrate_pages) ENTRY_COMP(openat) /* 275 */ ENTRY_SAME(mkdirat) -- cgit v0.10.2 From f295c79b6766b25fe8c1aad88211c54d1caa7e0b Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 10 Feb 2006 18:02:44 -0800 Subject: IB/mthca: Don't print debugging info until we have all values When debugging is enabled, the mthca_QUERY_DEV_LIM() firmware command function prints out some of the device limits that it queries. However the debugging prints happen before all of the fields are extracted from the firmware response, so some of the values that get printed are uninitialized junk. Move the prints to the end of the function to fix this. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index f9b9b93..2825615 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -1029,25 +1029,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, MTHCA_GET(size, outbox, QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET); dev_lim->uar_scratch_entry_sz = size; - mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", - dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz); - mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", - dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz); - mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", - dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz); - mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", - dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz); - mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", - dev_lim->reserved_mrws, dev_lim->reserved_mtts); - mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", - dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars); - mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", - dev_lim->max_pds, dev_lim->reserved_mgms); - mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", - dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz); - - mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); - if (mthca_is_memfree(dev)) { MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); dev_lim->max_srq_sz = 1 << field; @@ -1093,6 +1074,25 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; } + mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", + dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz); + mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", + dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz); + mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", + dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz); + mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", + dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz); + mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", + dev_lim->reserved_mrws, dev_lim->reserved_mtts); + mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", + dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars); + mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", + dev_lim->max_pds, dev_lim->reserved_mgms); + mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", + dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz); + + mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); + out: mthca_free_mailbox(dev, mailbox); return err; -- cgit v0.10.2 From 20b83382d1c5d4d1a73fc5671261db5239d1dbb3 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Sat, 11 Feb 2006 12:22:12 -0800 Subject: IPoIB: Yet another fix for send-only joins Even after the last fix, it's still possible for a send-only join to start before the join for the broadcast group has finished. This could cause us to create a multicast group using attributes from the broadcast group that haven't been initialized yet, so we would use garbage for the Q_Key, etc. Fix this by waiting until the broadcast group's attached flag is set before starting send-only joins. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 932bf13..a2408d7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -533,8 +533,10 @@ void ipoib_mcast_join_task(void *dev_ptr) } if (!priv->broadcast) { - priv->broadcast = ipoib_mcast_alloc(dev, 1); - if (!priv->broadcast) { + struct ipoib_mcast *broadcast; + + broadcast = ipoib_mcast_alloc(dev, 1); + if (!broadcast) { ipoib_warn(priv, "failed to allocate broadcast group\n"); mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) @@ -544,10 +546,11 @@ void ipoib_mcast_join_task(void *dev_ptr) return; } - memcpy(priv->broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, + spin_lock_irq(&priv->lock); + memcpy(broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, sizeof (union ib_gid)); + priv->broadcast = broadcast; - spin_lock_irq(&priv->lock); __ipoib_mcast_add(dev, priv->broadcast); spin_unlock_irq(&priv->lock); } @@ -701,7 +704,9 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, */ spin_lock(&priv->lock); - if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || !priv->broadcast) { + if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || + !priv->broadcast || + !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { ++priv->stats.tx_dropped; dev_kfree_skb_any(skb); goto unlock; -- cgit v0.10.2 From 4733804c9f62fbc17ba69e8654a5fdf465f5bc41 Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 8 Feb 2006 20:57:42 -0600 Subject: [SCSI] ipr: Fix adapter initialization failure Since scsi core is always sending scatterlists now, remove some code which was written with the bad assumption that a small transfer would not be sent down in a scatterlist. Without this fix, the ipr driver ends up sending garbage data to the adapter following a reset, causing it to fail the reset and take the adapter offline. Signed-off-by: Brian King Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 27acf78..2bba5e5 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4236,35 +4236,6 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) } /** - * ipr_save_ioafp_mode_select - Save adapters mode select data - * @ioa_cfg: ioa config struct - * @scsi_cmd: scsi command struct - * - * This function saves mode select data for the adapter to - * use following an adapter reset. - * - * Return value: - * 0 on success / SCSI_MLQUEUE_HOST_BUSY on failure - **/ -static int ipr_save_ioafp_mode_select(struct ipr_ioa_cfg *ioa_cfg, - struct scsi_cmnd *scsi_cmd) -{ - if (!ioa_cfg->saved_mode_pages) { - ioa_cfg->saved_mode_pages = kmalloc(sizeof(struct ipr_mode_pages), - GFP_ATOMIC); - if (!ioa_cfg->saved_mode_pages) { - dev_err(&ioa_cfg->pdev->dev, - "IOA mode select buffer allocation failed\n"); - return SCSI_MLQUEUE_HOST_BUSY; - } - } - - memcpy(ioa_cfg->saved_mode_pages, scsi_cmd->buffer, scsi_cmd->cmnd[4]); - ioa_cfg->saved_mode_page_len = scsi_cmd->cmnd[4]; - return 0; -} - -/** * ipr_queuecommand - Queue a mid-layer request * @scsi_cmd: scsi command struct * @done: done function @@ -4338,9 +4309,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; - if (ipr_is_ioa_resource(res) && scsi_cmd->cmnd[0] == MODE_SELECT) - rc = ipr_save_ioafp_mode_select(ioa_cfg, scsi_cmd); - if (likely(rc == 0)) rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); @@ -4829,17 +4797,11 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) int length; ENTER; - if (ioa_cfg->saved_mode_pages) { - memcpy(mode_pages, ioa_cfg->saved_mode_pages, - ioa_cfg->saved_mode_page_len); - length = ioa_cfg->saved_mode_page_len; - } else { - ipr_scsi_bus_speed_limit(ioa_cfg); - ipr_check_term_power(ioa_cfg, mode_pages); - ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages); - length = mode_pages->hdr.length + 1; - mode_pages->hdr.length = 0; - } + ipr_scsi_bus_speed_limit(ioa_cfg); + ipr_check_term_power(ioa_cfg, mode_pages); + ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages); + length = mode_pages->hdr.length + 1; + mode_pages->hdr.length = 0; ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), @@ -5969,7 +5931,6 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg) } ipr_free_dump(ioa_cfg); - kfree(ioa_cfg->saved_mode_pages); kfree(ioa_cfg->trace); } diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b639332..fd360bf 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -36,8 +36,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.1.1" -#define IPR_DRIVER_DATE "(November 15, 2005)" +#define IPR_DRIVER_VERSION "2.1.2" +#define IPR_DRIVER_DATE "(February 8, 2006)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -1000,7 +1000,6 @@ struct ipr_ioa_cfg { struct Scsi_Host *host; struct pci_dev *pdev; struct ipr_sglist *ucode_sglist; - struct ipr_mode_pages *saved_mode_pages; u8 saved_mode_page_len; struct work_struct work_q; -- cgit v0.10.2 From 3542adcb354fea4fca792d36b91cb44d0da147e5 Mon Sep 17 00:00:00 2001 From: "Ju, Seokmann" Date: Thu, 9 Feb 2006 12:32:59 -0700 Subject: [SCSI] megaraid_legacy: kobject_register failure Attached patch fixes problem that cause kobject_register failure during loading. Kobject_register would fail when there are more than 1 module with same module name. This patch will change module name of megaraid_legacy from 'megaraid' to 'megaraid_legacy'. Signed-Off-by: Seokmann Ju Signed-off-by: James Bottomley diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index d101a8a..7144674 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -5049,7 +5049,7 @@ static struct pci_device_id megaraid_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl); static struct pci_driver megaraid_pci_driver = { - .name = "megaraid", + .name = "megaraid_legacy", .id_table = megaraid_pci_tbl, .probe = megaraid_probe_one, .remove = __devexit_p(megaraid_remove_one), diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 4b3e0d6..4b75fe6 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -5,7 +5,7 @@ #include #define MEGARAID_VERSION \ - "v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n" + "v2.00.4 (Release Date: Thu Feb 9 08:51:30 EST 2006)\n" /* * Driver features - change the values to enable or disable features in the -- cgit v0.10.2 From c8024eb549f0c701e6d1c46c32e997f06f05d76d Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sat, 11 Feb 2006 01:40:11 +0100 Subject: [SCSI] zfcp: get rid of physical_wwpn and physical_s_id Remove all remainders of obsolete zfcp adapter attributes physical_wwpn and physical_s_id. Signed-off-by: Andreas Herrmann Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index e260d19..7dac56c 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -915,8 +915,6 @@ struct zfcp_adapter { wwn_t peer_wwnn; /* P2P peer WWNN */ wwn_t peer_wwpn; /* P2P peer WWPN */ u32 peer_d_id; /* P2P peer D_ID */ - wwn_t physical_wwpn; /* WWPN of physical port */ - u32 physical_s_id; /* local FC port ID */ struct ccw_device *ccw_device; /* S/390 ccw device */ u8 fc_service_class; u32 hydra_version; /* Hydra version */ diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c index dfc0737..b29ac25 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c @@ -55,8 +55,6 @@ ZFCP_DEFINE_ADAPTER_ATTR(status, "0x%08x\n", atomic_read(&adapter->status)); ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn); ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn); ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id); -ZFCP_DEFINE_ADAPTER_ATTR(physical_wwpn, "0x%016llx\n", adapter->physical_wwpn); -ZFCP_DEFINE_ADAPTER_ATTR(physical_s_id, "0x%06x\n", adapter->physical_s_id); ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version); ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version); ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n", @@ -241,8 +239,6 @@ static struct attribute *zfcp_adapter_attrs[] = { &dev_attr_peer_wwnn.attr, &dev_attr_peer_wwpn.attr, &dev_attr_peer_d_id.attr, - &dev_attr_physical_wwpn.attr, - &dev_attr_physical_s_id.attr, &dev_attr_card_version.attr, &dev_attr_lic_version.attr, &dev_attr_status.attr, -- cgit v0.10.2 From 2f8f3ed5fc566700cf45d422f4cf1624bd123d93 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sat, 11 Feb 2006 01:41:50 +0100 Subject: [SCSI] zfcp: fix adapter erp when link is unplugged Remove endless polling for replug of the local link. Just wait for link up notification. Signed-off-by: Andreas Herrmann Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 7dac56c..f031199 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -152,11 +152,6 @@ typedef u32 scsi_lun_t; #define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 100 #define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7 -/* Retry 5 times every 2 second, then every minute */ -#define ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES 5 -#define ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP 200 -#define ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP 6000 - /* timeout value for "default timer" for fsf requests */ #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ); diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index da947e6..8ed6fcb 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -2246,15 +2246,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) { int retval; - if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, - &erp_action->adapter->status)) && - (erp_action->adapter->adapter_features & - FSF_FEATURE_HBAAPI_MANAGEMENT)) { - zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); - atomic_set(&erp_action->adapter->erp_counter, 0); - return ZFCP_ERP_FAILED; - } - retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); if (retval == ZFCP_ERP_FAILED) return ZFCP_ERP_FAILED; @@ -2266,13 +2257,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); } -/* - * function: - * - * purpose: - * - * returns: - */ static int zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) { @@ -2350,48 +2334,40 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) { int ret; - int retries; - int sleep; - struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_adapter *adapter; + adapter = erp_action->adapter; atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); - retries = 0; - do { - write_lock(&adapter->erp_lock); - zfcp_erp_action_to_running(erp_action); - write_unlock(&adapter->erp_lock); - zfcp_erp_timeout_init(erp_action); - ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); - if (ret == -EOPNOTSUPP) { - debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); - return ZFCP_ERP_SUCCEEDED; - } else if (ret) { - debug_text_event(adapter->erp_dbf, 3, "a_xport_failed"); - return ZFCP_ERP_FAILED; - } - debug_text_event(adapter->erp_dbf, 6, "a_xport_ok"); + write_lock(&adapter->erp_lock); + zfcp_erp_action_to_running(erp_action); + write_unlock(&adapter->erp_lock); - down(&adapter->erp_ready_sem); - if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { - ZFCP_LOG_INFO("error: exchange of port data " - "for adapter %s timed out\n", - zfcp_get_busid_by_adapter(adapter)); - break; - } - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, - &adapter->status)) - break; + zfcp_erp_timeout_init(erp_action); + ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); + if (ret == -EOPNOTSUPP) { + debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); + return ZFCP_ERP_SUCCEEDED; + } else if (ret) { + debug_text_event(adapter->erp_dbf, 3, "a_xport_failed"); + return ZFCP_ERP_FAILED; + } + debug_text_event(adapter->erp_dbf, 6, "a_xport_ok"); - if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) { - sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP; - retries++; - } else - sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP; - schedule_timeout(sleep); - } while (1); + ret = ZFCP_ERP_SUCCEEDED; + down(&adapter->erp_ready_sem); + if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { + ZFCP_LOG_INFO("error: exchange port data timed out (adapter " + "%s)\n", zfcp_get_busid_by_adapter(adapter)); + ret = ZFCP_ERP_FAILED; + } + if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) { + ZFCP_LOG_INFO("error: exchange port data failed (adapter " + "%s\n", zfcp_get_busid_by_adapter(adapter)); + ret = ZFCP_ERP_FAILED; + } - return ZFCP_ERP_SUCCEEDED; + return ret; } /* diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 9f0cb3d..bd8cd4d 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -388,6 +388,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) case FSF_PROT_LINK_DOWN: zfcp_fsf_link_down_info_eval(adapter, &prot_status_qual->link_down_info); + zfcp_erp_adapter_reopen(adapter, 0); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -558,10 +559,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); - if (link_down == NULL) { - zfcp_erp_adapter_reopen(adapter, 0); - return; - } + if (link_down == NULL) + goto out; switch (link_down->error_code) { case FSF_PSQ_LINK_NO_LIGHT: @@ -643,16 +642,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, link_down->explanation_code, link_down->vendor_specific_code); - switch (link_down->error_code) { - case FSF_PSQ_LINK_NO_LIGHT: - case FSF_PSQ_LINK_WRAP_PLUG: - case FSF_PSQ_LINK_NO_FCP: - case FSF_PSQ_LINK_FIRMWARE_UPDATE: - zfcp_erp_adapter_reopen(adapter, 0); - break; - default: - zfcp_erp_adapter_failed(adapter); - } + out: + zfcp_erp_adapter_failed(adapter); } /* @@ -2304,6 +2295,35 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, return retval; } +/** + * zfcp_fsf_exchange_port_evaluate + * @fsf_req: fsf_req which belongs to xchg port data request + * @xchg_ok: specifies if xchg port data was incomplete or complete (0/1) + */ +static void +zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) +{ + struct zfcp_adapter *adapter; + struct fsf_qtcb *qtcb; + struct fsf_qtcb_bottom_port *bottom, *data; + struct Scsi_Host *shost; + + adapter = fsf_req->adapter; + qtcb = fsf_req->qtcb; + bottom = &qtcb->bottom.port; + shost = adapter->scsi_host; + + data = (struct fsf_qtcb_bottom_port*) fsf_req->data; + if (data) + memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); + + if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) + fc_host_permanent_port_name(shost) = bottom->wwpn; + else + fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + fc_host_maxframe_size(shost) = bottom->maximum_frame_size; + fc_host_supported_speeds(shost) = bottom->supported_speed; +} /** * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request @@ -2312,38 +2332,26 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) { - struct zfcp_adapter *adapter = fsf_req->adapter; - struct Scsi_Host *shost = adapter->scsi_host; - struct fsf_qtcb *qtcb = fsf_req->qtcb; - struct fsf_qtcb_bottom_port *bottom, *data; + struct zfcp_adapter *adapter; + struct fsf_qtcb *qtcb; + + adapter = fsf_req->adapter; + qtcb = fsf_req->qtcb; if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) return; switch (qtcb->header.fsf_status) { case FSF_GOOD: + zfcp_fsf_exchange_port_evaluate(fsf_req, 1); atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); - - bottom = &qtcb->bottom.port; - data = (struct fsf_qtcb_bottom_port*) fsf_req->data; - if (data) - memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) - fc_host_permanent_port_name(shost) = bottom->wwpn; - else - fc_host_permanent_port_name(shost) = - fc_host_port_name(shost); - fc_host_maxframe_size(shost) = bottom->maximum_frame_size; - fc_host_supported_speeds(shost) = bottom->supported_speed; break; - case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: + zfcp_fsf_exchange_port_evaluate(fsf_req, 0); atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); - zfcp_fsf_link_down_info_eval(adapter, &qtcb->header.fsf_status_qual.link_down_info); break; - default: debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng"); debug_event(adapter->erp_dbf, 0, -- cgit v0.10.2 From ed829ad607a9c334cea490d3a8c0f874153fb42d Mon Sep 17 00:00:00 2001 From: Maxim Shchetynin Date: Sat, 11 Feb 2006 01:42:58 +0100 Subject: [SCSI] zfcp: fix logging during device reset Avoid access to old fsf_requests if device reset is logged. Signed-off-by: Maxim Shchetynin Signed-off-by: Andreas Herrmann Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 4d7d47c..a5f2ba9 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -710,10 +710,9 @@ static inline void _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, struct zfcp_adapter *adapter, struct scsi_cmnd *scsi_cmnd, - struct zfcp_fsf_req *new_fsf_req) + struct zfcp_fsf_req *fsf_req, + struct zfcp_fsf_req *old_fsf_req) { - struct zfcp_fsf_req *fsf_req = - (struct zfcp_fsf_req *)scsi_cmnd->host_scribble; struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; unsigned long flags; @@ -727,19 +726,20 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, if (offset == 0) { strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); - if (scsi_cmnd->device) { - rec->scsi_id = scsi_cmnd->device->id; - rec->scsi_lun = scsi_cmnd->device->lun; + if (scsi_cmnd != NULL) { + if (scsi_cmnd->device) { + rec->scsi_id = scsi_cmnd->device->id; + rec->scsi_lun = scsi_cmnd->device->lun; + } + rec->scsi_result = scsi_cmnd->result; + rec->scsi_cmnd = (unsigned long)scsi_cmnd; + rec->scsi_serial = scsi_cmnd->serial_number; + memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd, + min((int)scsi_cmnd->cmd_len, + ZFCP_DBF_SCSI_OPCODE)); + rec->scsi_retries = scsi_cmnd->retries; + rec->scsi_allowed = scsi_cmnd->allowed; } - rec->scsi_result = scsi_cmnd->result; - rec->scsi_cmnd = (unsigned long)scsi_cmnd; - rec->scsi_serial = scsi_cmnd->serial_number; - memcpy(rec->scsi_opcode, - &scsi_cmnd->cmnd, - min((int)scsi_cmnd->cmd_len, - ZFCP_DBF_SCSI_OPCODE)); - rec->scsi_retries = scsi_cmnd->retries; - rec->scsi_allowed = scsi_cmnd->allowed; if (fsf_req != NULL) { fcp_rsp = (struct fcp_rsp_iu *) &(fsf_req->qtcb->bottom.io.fcp_rsp); @@ -772,15 +772,8 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, rec->fsf_seqno = fsf_req->seq_no; rec->fsf_issued = fsf_req->issued; } - if (new_fsf_req != NULL) { - rec->type.new_fsf_req.fsf_reqid = - (unsigned long) - new_fsf_req; - rec->type.new_fsf_req.fsf_seqno = - new_fsf_req->seq_no; - rec->type.new_fsf_req.fsf_issued = - new_fsf_req->issued; - } + rec->type.old_fsf_reqid = + (unsigned long) old_fsf_req; } else { strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); dump->total_size = buflen; @@ -801,19 +794,21 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, inline void zfcp_scsi_dbf_event_result(const char *tag, int level, struct zfcp_adapter *adapter, - struct scsi_cmnd *scsi_cmnd) + struct scsi_cmnd *scsi_cmnd, + struct zfcp_fsf_req *fsf_req) { - _zfcp_scsi_dbf_event_common("rslt", - tag, level, adapter, scsi_cmnd, NULL); + _zfcp_scsi_dbf_event_common("rslt", tag, level, + adapter, scsi_cmnd, fsf_req, NULL); } inline void zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, struct scsi_cmnd *scsi_cmnd, - struct zfcp_fsf_req *new_fsf_req) + struct zfcp_fsf_req *new_fsf_req, + struct zfcp_fsf_req *old_fsf_req) { - _zfcp_scsi_dbf_event_common("abrt", - tag, 1, adapter, scsi_cmnd, new_fsf_req); + _zfcp_scsi_dbf_event_common("abrt", tag, 1, + adapter, scsi_cmnd, new_fsf_req, old_fsf_req); } inline void @@ -823,7 +818,7 @@ zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, struct zfcp_adapter *adapter = unit->port->adapter; _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", - tag, 1, adapter, scsi_cmnd, NULL); + tag, 1, adapter, scsi_cmnd, NULL, NULL); } static int @@ -856,6 +851,10 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, rec->scsi_retries); len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", rec->scsi_allowed); + if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { + len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx", + rec->type.old_fsf_reqid); + } len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", rec->fsf_reqid); len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", @@ -883,21 +882,6 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, min((int)rec->type.fcp.sns_info_len, ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, rec->type.fcp.sns_info_len); - } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { - len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx", - rec->type.new_fsf_req.fsf_reqid); - len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x", - rec->type.new_fsf_req.fsf_seqno); - len += zfcp_dbf_stck(out_buf + len, "fsf_issued", - rec->type.new_fsf_req.fsf_issued); - } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) || - (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) { - len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx", - rec->type.new_fsf_req.fsf_reqid); - len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x", - rec->type.new_fsf_req.fsf_seqno); - len += zfcp_dbf_stck(out_buf + len, "fsf_issued", - rec->type.new_fsf_req.fsf_issued); } len += sprintf(out_buf + len, "\n"); diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index f031199..7f551d6 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -424,11 +424,7 @@ struct zfcp_scsi_dbf_record { u32 fsf_seqno; u64 fsf_issued; union { - struct { - u64 fsf_reqid; - u32 fsf_seqno; - u64 fsf_issued; - } new_fsf_req; + u64 old_fsf_reqid; struct { u8 rsp_validity; u8 rsp_scsi_status; diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index c1ba7cf..700f540 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -194,9 +194,10 @@ extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *); extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, - struct scsi_cmnd *); + struct scsi_cmnd *, + struct zfcp_fsf_req *); extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, - struct scsi_cmnd *, + struct scsi_cmnd *, struct zfcp_fsf_req *, struct zfcp_fsf_req *); extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, struct scsi_cmnd *); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index bd8cd4d..662ec57 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -4211,11 +4211,11 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); if (scpnt->result != 0) - zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt); + zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req); else if (scpnt->retries > 0) - zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt); + zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req); else - zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt); + zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req); /* cleanup pointer (need this especially for abort) */ scpnt->host_scribble = NULL; diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index e080375..9f6b4d7 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -242,7 +242,7 @@ zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) zfcp_scsi_dbf_event_result("fail", 4, (struct zfcp_adapter*) scpnt->device->host->hostdata[0], - scpnt); + scpnt, NULL); /* return directly */ scpnt->scsi_done(scpnt); } @@ -446,7 +446,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; if (!old_fsf_req) { write_unlock_irqrestore(&adapter->abort_lock, flags); - zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req); + zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, NULL); retval = SUCCESS; goto out; } @@ -460,6 +460,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) adapter, unit, 0); if (!new_fsf_req) { ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); + zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, + old_fsf_req); retval = FAILED; goto out; } @@ -470,13 +472,16 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) /* status should be valid since signals were not permitted */ if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { - zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req); + zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req, + NULL); retval = SUCCESS; } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { - zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req); + zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req, + NULL); retval = SUCCESS; } else { - zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req); + zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req, + NULL); retval = FAILED; } zfcp_fsf_req_free(new_fsf_req); -- cgit v0.10.2 From 61c41823c50302ca6cd455c48a1395f944c61f8f Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sat, 11 Feb 2006 01:43:55 +0100 Subject: [SCSI] zfcp: fix: avoid race between fc_remote_port_add and scsi_add_device Flush workqueue of a scsi host after a remote port for that host is registered at the fc transport class. Otherwise immediate registration of a scsi device on that host is racy. Signed-off-by: Andreas Herrmann Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 8ed6fcb..e3c4bdd 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -3415,6 +3415,8 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, "(adapter %s, wwpn=0x%016Lx)\n", zfcp_get_busid_by_port(port), port->wwpn); + else + scsi_flush_work(adapter->scsi_host); } zfcp_port_put(port); break; -- cgit v0.10.2 From e2230eac17486e2ee07091d54d898eb40bcd0fdd Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 12 Feb 2006 09:28:19 -0700 Subject: [SCSI] sym2: Mask off opcode from RBC pm->sg.size is set from the Residual Byte Count register. However, the upper byte of the RBC is the opcode of the instruction that was executing, so we need to mask it off. This fixes some spurious rejects of IGNORE WIDE RESIDUE messages. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 8260f04..f4854c3 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -3588,7 +3588,7 @@ static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int if (pm) { dp_scr = scr_to_cpu(pm->ret); - dp_ofs -= scr_to_cpu(pm->sg.size); + dp_ofs -= scr_to_cpu(pm->sg.size) & 0x00ffffff; } /* -- cgit v0.10.2 From 40ad7a6afc53217ad95b5ae2221e42d7655e057b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Feb 2006 23:30:11 -0800 Subject: [SPARC]: sys_newfstatat --> sys_fstatat64 Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index c031470..768de64 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -76,7 +76,7 @@ sys_call_table: /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat -/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat +/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 9264ccb..417727b 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -428,6 +428,27 @@ asmlinkage long compat_sys_fstat64(unsigned int fd, return error; } +asmlinkage long compat_sys_fstatat64(unsigned int dfd, char __user *filename, + struct compat_stat64 __user * statbuf, int flag) +{ + struct kstat stat; + int error = -EINVAL; + + if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) + goto out; + + if (flag & AT_SYMLINK_NOFOLLOW) + error = vfs_lstat_fd(dfd, filename, &stat); + else + error = vfs_stat_fd(dfd, filename, &stat); + + if (!error) + error = cp_compat_stat64(&stat, statbuf); + +out: + return error; +} + asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) { return sys_sysfs(option, arg1, arg2); diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index a191685..c3adb7a 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -77,7 +77,7 @@ sys_call_table32: /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat - .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat + .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare @@ -146,7 +146,7 @@ sys_call_table: /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat - .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat + .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 0615d60..64ec640 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -305,7 +305,7 @@ #define __NR_mknodat 286 #define __NR_fchownat 287 #define __NR_futimesat 288 -#define __NR_newfstatat 289 +#define __NR_fstatat64 289 #define __NR_unlinkat 290 #define __NR_renameat 291 #define __NR_linkat 292 diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index c58ba8a..a284986 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -307,7 +307,7 @@ #define __NR_mknodat 286 #define __NR_fchownat 287 #define __NR_futimesat 288 -#define __NR_newfstatat 289 +#define __NR_fstatat64 289 #define __NR_unlinkat 290 #define __NR_renameat 291 #define __NR_linkat 292 -- cgit v0.10.2 From 56f3a40a5e7586043260669cc794e56fa58339e1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 11:39:57 +0100 Subject: [Bluetooth] Reduce L2CAP MTU for RFCOMM connections This patch reduces the default L2CAP MTU for all RFCOMM connections from 1024 to 1013 to improve the interoperability with some broken RFCOMM implementations. To make this more flexible the L2CAP MTU becomes also a module parameter and so it can changed at runtime. Signed-off-by: Marcel Holtmann diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index bbfac86..89d743c 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -33,7 +33,7 @@ #define RFCOMM_DEFAULT_MTU 127 #define RFCOMM_DEFAULT_CREDITS 7 -#define RFCOMM_MAX_L2CAP_MTU 1024 +#define RFCOMM_MAX_L2CAP_MTU 1013 #define RFCOMM_MAX_CREDITS 40 #define RFCOMM_SKB_HEAD_RESERVE 8 diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 0d89d64..5b4253c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -46,13 +46,15 @@ #include #include -#define VERSION "1.6" - #ifndef CONFIG_BT_RFCOMM_DEBUG #undef BT_DBG #define BT_DBG(D...) #endif +#define VERSION "1.7" + +static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; + static struct task_struct *rfcomm_thread; static DECLARE_MUTEX(rfcomm_sem); @@ -623,7 +625,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst /* Set L2CAP options */ sk = sock->sk; lock_sock(sk); - l2cap_pi(sk)->imtu = RFCOMM_MAX_L2CAP_MTU; + l2cap_pi(sk)->imtu = l2cap_mtu; release_sock(sk); s = rfcomm_session_add(sock, BT_BOUND); @@ -1868,7 +1870,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) /* Set L2CAP options */ sk = sock->sk; lock_sock(sk); - l2cap_pi(sk)->imtu = RFCOMM_MAX_L2CAP_MTU; + l2cap_pi(sk)->imtu = l2cap_mtu; release_sock(sk); /* Start listening on the socket */ @@ -2070,6 +2072,9 @@ static void __exit rfcomm_exit(void) module_init(rfcomm_init); module_exit(rfcomm_exit); +module_param(l2cap_mtu, uint, 0644); +MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); + MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION); MODULE_VERSION(VERSION); -- cgit v0.10.2 From 7b005bd34c895ebeefd1c62f90a329730b88946b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 11:40:03 +0100 Subject: [Bluetooth] Fix NULL pointer dereferences of the HCI socket This patch fixes the two NULL pointer dereferences found by the sfuzz tool from Ilja van Sprundel. The first one was a call of getsockname() for an unbound socket and the second was calling accept() while this operation isn't implemented for the HCI socket interface. Signed-off-by: Marcel Holtmann diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index bdb6458..97bdec7 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -143,13 +143,15 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) static int hci_sock_release(struct socket *sock) { struct sock *sk = sock->sk; - struct hci_dev *hdev = hci_pi(sk)->hdev; + struct hci_dev *hdev; BT_DBG("sock %p sk %p", sock, sk); if (!sk) return 0; + hdev = hci_pi(sk)->hdev; + bt_sock_unlink(&hci_sk_list, sk); if (hdev) { @@ -311,14 +313,18 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *add { struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; struct sock *sk = sock->sk; + struct hci_dev *hdev = hci_pi(sk)->hdev; BT_DBG("sock %p sk %p", sock, sk); + if (!hdev) + return -EBADFD; + lock_sock(sk); *addr_len = sizeof(*haddr); haddr->hci_family = AF_BLUETOOTH; - haddr->hci_dev = hci_pi(sk)->hdev->id; + haddr->hci_dev = hdev->id; release_sock(sk); return 0; -- cgit v0.10.2 From 9225806386e398eeba46958a7befa017bda73f58 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 11:40:07 +0100 Subject: [Bluetooth] Fix firmware loading problem of BT3C driver Before the PCMCIA subsystem was fully integrated into the device and driver model, the BT3C driver had to workaround this when loading the firmware. This workaround is broken and makes the driver oops when loading the firmware. This patch removes this workaround and uses now the provided device structure from the PCMCIA subsystem. Signed-off-by: Marcel Holtmann diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index e522d19..7e21b1f 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -474,18 +474,6 @@ static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long /* ======================== Card services HCI interaction ======================== */ -static struct device *bt3c_device(void) -{ - static struct device dev = { - .bus_id = "pcmcia", - }; - kobject_set_name(&dev.kobj, "bt3c"); - kobject_init(&dev.kobj); - - return &dev; -} - - static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count) { char *ptr = (char *) firmware; @@ -574,6 +562,7 @@ static int bt3c_open(bt3c_info_t *info) { const struct firmware *firmware; struct hci_dev *hdev; + client_handle_t handle; int err; spin_lock_init(&(info->lock)); @@ -605,8 +594,10 @@ static int bt3c_open(bt3c_info_t *info) hdev->owner = THIS_MODULE; + handle = info->link.handle; + /* Load firmware */ - err = request_firmware(&firmware, "BT3CPCC.bin", bt3c_device()); + err = request_firmware(&firmware, "BT3CPCC.bin", &handle_to_dev(handle)); if (err < 0) { BT_ERR("Firmware request failed"); goto error; -- cgit v0.10.2 From 326a625748535c4cdb1c632b1dcb07030989a393 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 13 Feb 2006 18:07:30 +0900 Subject: [PATCH] MIPS 32bit machines need fstatat64 support. As noted by Jan Dittmer Signed-off-by: Yoichi Yuasa Signed-off-by: Linus Torvalds diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index d7c4a38..d83e033 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -623,7 +623,7 @@ einval: li v0, -EINVAL sys sys_mknodat 4 /* 4290 */ sys sys_fchownat 5 sys sys_futimesat 3 - sys sys_newfstatat 4 + sys sys_fstatat64 4 sys sys_unlinkat 3 sys sys_renameat 4 /* 4295 */ sys sys_linkat 4 -- cgit v0.10.2 From 90947ef26fa689a3252aa8282a01f60648e70fdb Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Mon, 13 Feb 2006 11:12:36 -0500 Subject: [PATCH] reiserfs: fix potential (unlikely) oops in reiserfs_get_acl This fixes a potential oops if there is an error reported by posix_acl_from_disk(). This is mostly theoretical due to the use of magics and checksums in xattrs, but is still possible. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 43de3ba..ab8894c 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -228,7 +228,8 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) acl = ERR_PTR(retval); } else { acl = posix_acl_from_disk(value, retval); - *p_acl = posix_acl_dup(acl); + if (!IS_ERR(acl)) + *p_acl = posix_acl_dup(acl); } kfree(value); -- cgit v0.10.2 From 75c0141ca2fdae7c332d8f17412fbe0939dd005f Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 13 Feb 2006 12:46:58 -0500 Subject: [PATCH] Remove "RV370 5B60 [Radeon X300 (PCIE)]" from DRI list I get a machine check exception, triple fault, or NMI watchdog lockup when DRI gets enabled on this card. (And Mauro Tassinari reports hung kernels too in http://lkml.org/lkml/2006/1/26/97) [ Adrian Bunk also states that this is the only RV350 entry for an RV370 in our lists, which implies that it's just buggy ] Cc: Adrian Bunk Cc: Dave Jones Cc: Mauro Tassinari Cc: Dave Airlie Signed-off-by: Linus Torvalds diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 8fd6357..2c17e88 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -85,7 +85,6 @@ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ -- cgit v0.10.2 From 7d2babc4874825027848db04d11784070da4456d Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 13 Feb 2006 12:19:44 -0800 Subject: IB/mthca: bump driver version and release date Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 2a165fd..e4810372 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -53,8 +53,8 @@ #define DRV_NAME "ib_mthca" #define PFX DRV_NAME ": " -#define DRV_VERSION "0.06" -#define DRV_RELDATE "June 23, 2005" +#define DRV_VERSION "0.07" +#define DRV_RELDATE "February 13, 2006" enum { MTHCA_FLAG_DDR_HIDDEN = 1 << 1, -- cgit v0.10.2 From 7a11c4d0635d9f6995736390b8c3346fe6f63d57 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Feb 2006 15:34:11 -0800 Subject: [IRDA]: Ratelimit messages. From: Joe Perches Based upon a patch by Dave Jones. Signed-off-by: Dave Jones Signed-off-by: David S. Miller diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index 05a8408..1880e46 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -82,9 +82,9 @@ do { if(!(expr)) { \ #define IRDA_ASSERT_LABEL(label) #endif /* CONFIG_IRDA_DEBUG */ -#define IRDA_WARNING(args...) printk(KERN_WARNING args) -#define IRDA_MESSAGE(args...) printk(KERN_INFO args) -#define IRDA_ERROR(args...) printk(KERN_ERR args) +#define IRDA_WARNING(args...) do { if (net_ratelimit()) printk(KERN_WARNING args); } while (0) +#define IRDA_MESSAGE(args...) do { if (net_ratelimit()) printk(KERN_INFO args); } while (0) +#define IRDA_ERROR(args...) do { if (net_ratelimit()) printk(KERN_ERR args); } while (0) /* * Magic numbers used by Linux-IrDA. Random numbers which must be unique to -- cgit v0.10.2 From bf3883c12fece9189ab4f7bb6e2690451db1366e Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 13 Feb 2006 15:34:58 -0800 Subject: [ATM]: Ratelimit atmsvc failure messages This seems to be trivial to trigger. Signed-off-by: Dave Jones Signed-off-by: David S. Miller diff --git a/net/atm/signaling.c b/net/atm/signaling.c index e7211a7..93ad59a 100644 --- a/net/atm/signaling.c +++ b/net/atm/signaling.c @@ -56,7 +56,8 @@ static void sigd_put_skb(struct sk_buff *skb) remove_wait_queue(&sigd_sleep,&wait); #else if (!sigd) { - printk(KERN_WARNING "atmsvc: no signaling demon\n"); + if (net_ratelimit()) + printk(KERN_WARNING "atmsvc: no signaling demon\n"); kfree_skb(skb); return; } -- cgit v0.10.2 From 77decfc716d460b3f7037bb19bd4eb12cd0dc996 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 13 Feb 2006 15:36:21 -0800 Subject: [IPV4] ICMP: Invert default for invalid icmp msgs sysctl isic can trigger these msgs to be spewed at a very high rate. There's already a sysctl to turn them off. Given these messages aren't useful for most people, this patch disables them by default. Signed-off-by: Dave Jones Signed-off-by: David S. Miller diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 4d1c409..e7bbff4 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -192,7 +192,7 @@ int sysctl_icmp_echo_ignore_all; int sysctl_icmp_echo_ignore_broadcasts = 1; /* Control parameter - ignore bogus broadcast responses? */ -int sysctl_icmp_ignore_bogus_error_responses; +int sysctl_icmp_ignore_bogus_error_responses = 1; /* * Configurable global rate limit. -- cgit v0.10.2 From 99e382afd297d91ab150ae46c28c4585f925818c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 13 Feb 2006 15:38:42 -0800 Subject: [P8023]: Fix tainting of kernel. Missing license tag. I've assumed this is GPL. (It could also use a MODULE_AUTHOR) Signed-off-by: Dave Jones Signed-off-by: David S. Miller diff --git a/net/802/p8023.c b/net/802/p8023.c index d23e906..53cf057 100644 --- a/net/802/p8023.c +++ b/net/802/p8023.c @@ -59,3 +59,5 @@ void destroy_8023_client(struct datalink_proto *dl) EXPORT_SYMBOL(destroy_8023_client); EXPORT_SYMBOL(make_8023_client); + +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From a6c1cd572642478528165ac44db4d2daae125a21 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 13 Feb 2006 15:42:48 -0800 Subject: [NETFILTER] Fix Kconfig menu level for x_tables The new x_tables related Kconfig options appear at the wrong menu level without this patch. Signed-off-by: Harald Welte Signed-off-by: David S. Miller diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 99c0a0f..0e55012 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -102,8 +102,6 @@ config NF_CT_NETLINK help This option enables support for a netlink-based userspace interface -endmenu - config NETFILTER_XTABLES tristate "Netfilter Xtables support (required for ip_tables)" help @@ -361,3 +359,5 @@ config NETFILTER_XT_MATCH_TCPMSS To compile it as a module, choose M here. If unsure, say N. +endmenu + -- cgit v0.10.2 From 178a3259f2508e786fb1bd6538365a167cee35c1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 13 Feb 2006 15:43:58 -0800 Subject: [BRIDGE]: Better fix for netfilter missing symbol has_bridge_parent Horms patch was the best of the three fixes. Dave, already applied Harald's version, so this patch converts that to the better one. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index c06cb09..6bb0c7e 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -805,8 +805,8 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, print_error: if (skb->dev != NULL) { printk("[%s]", skb->dev->name); - if (bridge_parent(skb->dev)) - printk("[%s]", bridge_parent(skb->dev)->name); + if (realoutdev) + printk("[%s]", realoutdev->name); } printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, skb->data); -- cgit v0.10.2 From e200bd8065e4db6297cd8db071a9188cf9aa6b56 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Mon, 13 Feb 2006 15:51:24 -0800 Subject: [NETLINK] genetlink: Fix bugs spotted by Andrew Morton. - panic() doesn't return. - Don't forget to unlock on genl_register_family() error path - genl_rcv_msg() is called via pointer so there's no point in declaring it `inline'. Notes: genl_ctrl_event() ignores the genlmsg_multicast() return value. lots of things ignore the genl_ctrl_event() return value. Signed-off-by: Jamal Hadi Salim Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 4ae1538..43e7241 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -238,7 +238,7 @@ int genl_register_family(struct genl_family *family) sizeof(struct nlattr *), GFP_KERNEL); if (family->attrbuf == NULL) { err = -ENOMEM; - goto errout; + goto errout_locked; } } else family->attrbuf = NULL; @@ -288,7 +288,7 @@ int genl_unregister_family(struct genl_family *family) return -ENOENT; } -static inline int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, +static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) { struct genl_ops *ops; @@ -375,7 +375,7 @@ static void genl_rcv(struct sock *sk, int len) do { if (genl_trylock()) return; - netlink_run_queue(sk, &qlen, &genl_rcv_msg); + netlink_run_queue(sk, &qlen, genl_rcv_msg); genl_unlock(); } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen); } @@ -549,10 +549,8 @@ static int __init genl_init(void) netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID, genl_rcv, THIS_MODULE); - if (genl_sock == NULL) { + if (genl_sock == NULL) panic("GENL: Cannot initialize generic netlink\n"); - return -ENOMEM; - } return 0; @@ -560,7 +558,6 @@ errout_register: genl_unregister_family(&genl_ctrl); errout: panic("GENL: Cannot register controller: %d\n", err); - return err; } subsys_initcall(genl_init); -- cgit v0.10.2 From 72fb630dad170084026bda6728b8d8f21ed48ff1 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 13 Feb 2006 15:53:41 -0800 Subject: [APPLETALK]: warning fix drivers/net/appletalk/cops.c: In function `cops_load': drivers/net/appletalk/cops.c:539: warning: assignment discards qualifiers from pointer target type drivers/net/appletalk/cops.c:547: warning: assignment discards qualifiers from pointer target type Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h index c68ba9c..fd2750b 100644 --- a/drivers/net/appletalk/cops.h +++ b/drivers/net/appletalk/cops.h @@ -51,7 +51,7 @@ struct ltfirmware { unsigned int length; - unsigned char * data; + const unsigned char *data; }; #define DAYNA 1 -- cgit v0.10.2 From 6d3e85ecf22a5e3610df47b9c3fb2fc32cfd35bf Mon Sep 17 00:00:00 2001 From: Nicolas DICHTEL Date: Mon, 13 Feb 2006 15:56:13 -0800 Subject: [IPV6] Don't store dst_entry for RAW socket Signed-off-by: Nicolas DICHTEL Signed-off-by: David S. Miller diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 738376c..ae20a0e 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -803,10 +803,7 @@ back_from_confirm: err = rawv6_push_pending_frames(sk, &fl, rp); } done: - ip6_dst_store(sk, dst, - ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? - &np->daddr : NULL); - + dst_release(dst); release_sock(sk); out: fl6_sock_release(flowlabel); -- cgit v0.10.2 From 00de651d14baabc5c1d2f32c49d9a984d8891c8e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 13 Feb 2006 16:01:27 -0800 Subject: [IPSEC]: Fix strange IPsec freeze. Problem discovered and initial patch by Olaf Kirch: there's a problem with IPsec that has been bugging some of our users for the last couple of kernel revs. Every now and then, IPsec will freeze the machine completely. This is with openswan user land, and with kernels up to and including 2.6.16-rc2. I managed to debug this a little, and what happens is that we end up looping in xfrm_lookup, and never get out. With a bit of debug printks added, I can this happening: ip_route_output_flow calls xfrm_lookup xfrm_find_bundle returns NULL (apparently we're in the middle of negotiating a new SA or something) We therefore call xfrm_tmpl_resolve. This returns EAGAIN We go to sleep, waiting for a policy update. Then we loop back to the top Apparently, the dst_orig that was passed into xfrm_lookup has been dropped from the routing table (obsolete=2) This leads to the endless loop, because we now create a new bundle, check the new bundle and find it's stale (stale_bundle -> xfrm_bundle_ok -> dst_check() return 0) People have been testing with the patch below, which seems to fix the problem partially. They still see connection hangs however (things only clear up when they start a new ping or new ssh). So the patch is obvsiouly not sufficient, and something else seems to go wrong. I'm grateful for any hints you may have... I suggest that we simply bail out always. If the dst decides to die on us later on, the packet will be dropped anyway. So there is no great urgency to retry here. Once we have the proper resolution queueing, we can then do the retry again. Signed-off-by: Herbert Xu Acked-by: Olaf Kirch Signed-off-by: David S. Miller diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index dbf4620..98ec53b 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -889,7 +889,9 @@ restart: xfrm_pol_put(policy); if (dst) dst_free(dst); - goto restart; + + err = -EHOSTUNREACH; + goto error; } dst->next = policy->bundles; policy->bundles = dst; -- cgit v0.10.2 From b4d9eda028e8becbb5057b554e63eea12e496a88 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Feb 2006 16:06:10 -0800 Subject: [NET]: Revert skb_copy_datagram_iovec() recursion elimination. Revert the following changeset: bc8dfcb93970ad7139c976356bfc99d7e251deaf Recursive SKB frag lists are really possible and disallowing them breaks things. Noticed by: Jesse Brandeburg Signed-off-by: David S. Miller diff --git a/net/core/datagram.c b/net/core/datagram.c index f8d322e..b8ce6bf 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -247,49 +247,74 @@ EXPORT_SYMBOL(skb_kill_datagram); int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, struct iovec *to, int len) { - int i, err, fraglen, end = 0; - struct sk_buff *next = skb_shinfo(skb)->frag_list; + int start = skb_headlen(skb); + int i, copy = start - offset; - if (!len) - return 0; + /* Copy header. */ + if (copy > 0) { + if (copy > len) + copy = len; + if (memcpy_toiovec(to, skb->data + offset, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + } -next_skb: - fraglen = skb_headlen(skb); - i = -1; + /* Copy paged appendix. Hmm... why does this look so complicated? */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; - while (1) { - int start = end; + BUG_TRAP(start <= offset + len); - if ((end += fraglen) > offset) { - int copy = end - offset, o = offset - start; + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + int err; + u8 *vaddr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + struct page *page = frag->page; if (copy > len) copy = len; - if (i == -1) - err = memcpy_toiovec(to, skb->data + o, copy); - else { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - struct page *page = frag->page; - void *p = kmap(page) + frag->page_offset + o; - err = memcpy_toiovec(to, p, copy); - kunmap(page); - } + vaddr = kmap(page); + err = memcpy_toiovec(to, vaddr + frag->page_offset + + offset - start, copy); + kunmap(page); if (err) goto fault; if (!(len -= copy)) return 0; offset += copy; } - if (++i >= skb_shinfo(skb)->nr_frags) - break; - fraglen = skb_shinfo(skb)->frags[i].size; + start = end; } - if (next) { - skb = next; - BUG_ON(skb_shinfo(skb)->frag_list); - next = skb->next; - goto next_skb; + + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_iovec(list, + offset - start, + to, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + start = end; + } } + if (!len) + return 0; + fault: return -EFAULT; } -- cgit v0.10.2 From 108dff7d2b721759b5e025ab18024967c1294792 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Mon, 13 Feb 2006 22:44:22 -0500 Subject: [PATCH] sys_newfstatat -> sys_fstatat64 parisc defines ARCH_WANT_STAT64, so we want to use fstatat64. It does not appear that it needs to be ENTRY_COMP, because struct stat64 is the same on both 32-bit and 64-bit (unlike on other platforms which did define a compat_sys_fstatat64.) Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin Signed-off-by: Linus Torvalds diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 66224f7..71011ea 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -385,7 +385,7 @@ ENTRY_SAME(mknodat) ENTRY_SAME(fchownat) ENTRY_COMP(futimesat) - ENTRY_COMP(newfstatat) /* 280 */ + ENTRY_SAME(fstatat64) /* 280 */ ENTRY_SAME(unlinkat) ENTRY_SAME(renameat) ENTRY_SAME(linkat) -- cgit v0.10.2 From a38408cd8d6bc0e5d16e609d4b1fdf9ba2e099ce Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 9 Feb 2006 16:35:31 -0500 Subject: [PATCH] USB: fix up the usb early handoff logic for EHCI Disable some dubious "early" USB handoff code that allegedly works around bugs on some systems (we don't know which ones) but rudely breaks some others. Also make the kernel warnings reporting BIOS handoff problems be more useful, reporting the register whose value displays the trouble. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index e9e5bc1..118288d 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -191,8 +191,9 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) } if (wait_time <= 0) printk(KERN_WARNING "%s %s: BIOS handoff " - "failed (BIOS bug ?)\n", - pdev->dev.bus_id, "OHCI"); + "failed (BIOS bug ?) %08x\n", + pdev->dev.bus_id, "OHCI", + readl(base + OHCI_CONTROL)); /* reset controller, preserving RWC */ writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); @@ -243,6 +244,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) pr_debug("%s %s: BIOS handoff\n", pdev->dev.bus_id, "EHCI"); +#if 0 +/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, + * but that seems dubious in general (the BIOS left it off intentionally) + * and is known to prevent some systems from booting. so we won't do this + * unless maybe we can determine when we're on a system that needs SMI forced. + */ /* BIOS workaround (?): be sure the * pre-Linux code receives the SMI */ @@ -252,6 +259,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, val | EHCI_USBLEGCTLSTS_SOOE); +#endif } /* always say Linux will own the hardware @@ -274,8 +282,8 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) * it down, and hope nothing goes too wrong */ printk(KERN_WARNING "%s %s: BIOS handoff " - "failed (BIOS bug ?)\n", - pdev->dev.bus_id, "EHCI"); + "failed (BIOS bug ?) %08x\n", + pdev->dev.bus_id, "EHCI", cap); pci_write_config_byte(pdev, offset + 2, 0); } -- cgit v0.10.2 From ba3e66e94b9fb8c2a370a90729e068314845549d Mon Sep 17 00:00:00 2001 From: Michael Hund Date: Thu, 2 Feb 2006 09:36:43 +0100 Subject: [PATCH] USB: add new device ids to ldusb Signed-off-by: Michael Hund Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 6f7a684..7724780 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1435,17 +1435,20 @@ void hid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 #define USB_VENDOR_ID_LD 0x0f11 -#define USB_DEVICE_ID_CASSY 0x1000 -#define USB_DEVICE_ID_POCKETCASSY 0x1010 -#define USB_DEVICE_ID_MOBILECASSY 0x1020 -#define USB_DEVICE_ID_JWM 0x1080 -#define USB_DEVICE_ID_DMMP 0x1081 -#define USB_DEVICE_ID_UMIP 0x1090 -#define USB_DEVICE_ID_VIDEOCOM 0x1200 -#define USB_DEVICE_ID_COM3LAB 0x2000 -#define USB_DEVICE_ID_TELEPORT 0x2010 -#define USB_DEVICE_ID_NETWORKANALYSER 0x2020 -#define USB_DEVICE_ID_POWERCONTROL 0x2030 +#define USB_DEVICE_ID_LD_CASSY 0x1000 +#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 +#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 +#define USB_DEVICE_ID_LD_JWM 0x1080 +#define USB_DEVICE_ID_LD_DMMP 0x1081 +#define USB_DEVICE_ID_LD_UMIP 0x1090 +#define USB_DEVICE_ID_LD_XRAY1 0x1100 +#define USB_DEVICE_ID_LD_XRAY2 0x1101 +#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 +#define USB_DEVICE_ID_LD_COM3LAB 0x2000 +#define USB_DEVICE_ID_LD_TELEPORT 0x2010 +#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 +#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 +#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 #define USB_VENDOR_ID_APPLE 0x05ac #define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 @@ -1491,17 +1494,20 @@ static const struct hid_blacklist { { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 331d4ae..e2d1198 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -24,6 +24,7 @@ * V0.1 (mh) Initial version * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint) * V0.12 (mh) Added kmalloc check for string buffer + * V0.13 (mh) Added support for LD X-Ray and Machine Test System */ #include @@ -40,17 +41,20 @@ /* Define these values to match your devices */ #define USB_VENDOR_ID_LD 0x0f11 /* USB Vendor ID of LD Didactic GmbH */ -#define USB_DEVICE_ID_CASSY 0x1000 /* USB Product ID for all CASSY-S modules */ -#define USB_DEVICE_ID_POCKETCASSY 0x1010 /* USB Product ID for Pocket-CASSY */ -#define USB_DEVICE_ID_MOBILECASSY 0x1020 /* USB Product ID for Mobile-CASSY */ -#define USB_DEVICE_ID_JWM 0x1080 /* USB Product ID for Joule and Wattmeter */ -#define USB_DEVICE_ID_DMMP 0x1081 /* USB Product ID for Digital Multimeter P (reserved) */ -#define USB_DEVICE_ID_UMIP 0x1090 /* USB Product ID for UMI P */ -#define USB_DEVICE_ID_VIDEOCOM 0x1200 /* USB Product ID for VideoCom */ -#define USB_DEVICE_ID_COM3LAB 0x2000 /* USB Product ID for COM3LAB */ -#define USB_DEVICE_ID_TELEPORT 0x2010 /* USB Product ID for Terminal Adapter */ -#define USB_DEVICE_ID_NETWORKANALYSER 0x2020 /* USB Product ID for Network Analyser */ -#define USB_DEVICE_ID_POWERCONTROL 0x2030 /* USB Product ID for Controlling device for Power Electronics */ +#define USB_DEVICE_ID_LD_CASSY 0x1000 /* USB Product ID of CASSY-S */ +#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 /* USB Product ID of Pocket-CASSY */ +#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 /* USB Product ID of Mobile-CASSY */ +#define USB_DEVICE_ID_LD_JWM 0x1080 /* USB Product ID of Joule and Wattmeter */ +#define USB_DEVICE_ID_LD_DMMP 0x1081 /* USB Product ID of Digital Multimeter P (reserved) */ +#define USB_DEVICE_ID_LD_UMIP 0x1090 /* USB Product ID of UMI P */ +#define USB_DEVICE_ID_LD_XRAY1 0x1100 /* USB Product ID of X-Ray Apparatus */ +#define USB_DEVICE_ID_LD_XRAY2 0x1101 /* USB Product ID of X-Ray Apparatus */ +#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 /* USB Product ID of VideoCom */ +#define USB_DEVICE_ID_LD_COM3LAB 0x2000 /* USB Product ID of COM3LAB */ +#define USB_DEVICE_ID_LD_TELEPORT 0x2010 /* USB Product ID of Terminal Adapter */ +#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 /* USB Product ID of Network Analyser */ +#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 /* USB Product ID of Converter Control Unit */ +#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 /* USB Product ID of Machine Test System */ #define USB_VENDOR_ID_VERNIER 0x08f7 #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 @@ -67,17 +71,20 @@ /* table of devices that work with this driver */ static struct usb_device_id ld_usb_table [] = { - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER) }, - { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, + { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, @@ -85,7 +92,7 @@ static struct usb_device_id ld_usb_table [] = { { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ld_usb_table); -MODULE_VERSION("V0.12"); +MODULE_VERSION("V0.13"); MODULE_AUTHOR("Michael Hund "); MODULE_DESCRIPTION("LD USB Driver"); MODULE_LICENSE("GPL"); @@ -632,8 +639,8 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * /* workaround for early firmware versions on fast computers */ if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) && - ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_CASSY) || - (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) && + ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_CASSY) || + (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) && (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { buffer = kmalloc(256, GFP_KERNEL); if (buffer == NULL) { -- cgit v0.10.2 From 343a65cadb3a6a102f08513d9c64eb7e317478f0 Mon Sep 17 00:00:00 2001 From: Michael Hund Date: Thu, 2 Feb 2006 09:37:02 +0100 Subject: [PATCH] USB: change ldusb's experimental state Signed-off-by: Michael Hund Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 6649531..8ba6a70 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -141,7 +141,7 @@ source "drivers/usb/misc/sisusbvga/Kconfig" config USB_LD tristate "USB LD driver" - depends on USB && EXPERIMENTAL + depends on USB help This driver is for generic USB devices that use interrupt transfers, like LD Didactic's USB devices. -- cgit v0.10.2 From c6c27721a42b991965bb792d5c196b8331d008d5 Mon Sep 17 00:00:00 2001 From: Christian Lindner Date: Wed, 1 Feb 2006 14:10:52 +0100 Subject: [PATCH] USB: PL2303: Leadtek 9531 GPS-Mouse The patch adds the USB ID (0413:2101) for the Leadtek GPS-Mouse 9531 to the driver pl2303. Signed-off-by: Christian Lindner Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index e8e575e..37c81c0 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -73,9 +73,10 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, - { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) }, - { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID ) }, + { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) }, + { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, + { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 1807087..9bc4755 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -71,3 +71,7 @@ #define SAGEM_VENDOR_ID 0x079b #define SAGEM_PRODUCT_ID 0x0027 + +/* Leadtek GPS 9531 (ID 0413:2101) */ +#define LEADTEK_VENDOR_ID 0x0413 +#define LEADTEK_9531_PRODUCT_ID 0x2101 -- cgit v0.10.2 From a0c53f1dca10acc93462339cbd0bf24b10d60a13 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 6 Feb 2006 12:15:15 -0800 Subject: [PATCH] USB: sl811_cs needs platform_device conversion too The switchover to "platform_driver" from "device_driver" missed one rather essential usage, which broke the sl811_cs driver ... this resolves the omission. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 466384d..134d200 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -101,7 +101,7 @@ static struct resource resources[] = { }, }; -extern struct device_driver sl811h_driver; +extern struct platform_driver sl811h_driver; static struct platform_device platform_dev = { .id = -1, @@ -132,7 +132,7 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) * initialized already because of the link order dependency created * by referencing "sl811h_driver". */ - platform_dev.name = sl811h_driver.name; + platform_dev.name = sl811h_driver.driver.name; return platform_device_register(&platform_dev); } -- cgit v0.10.2 From a2149bce2535047371a1309f032f0320b05db791 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 2 Feb 2006 09:52:45 -0500 Subject: [PATCH] usb-storage: new unusual_devs entry This patch (as631) for unusual_devs.h fixes bugzilla entry 5913. Signed-off-by: Alan Stern Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index ee958f9..c5d6d84 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1162,6 +1162,13 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, US_FL_SINGLE_LUN), #endif +/* Reported by Andrew Simmons */ +UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, + "DataStor", + "USB4500 FW1.04", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Control/Bulk transport for all SubClass values */ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), -- cgit v0.10.2 From ba3e93ad3c6e511f68c1b3e46954feff6cdd5a62 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 30 Jan 2006 10:19:43 -0500 Subject: [PATCH] usb-storage: unusual_devs entry Here is a new entry for unusual_devs.h (as630). Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c5d6d84..6e32615 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -946,6 +946,12 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_BULK32), +/* Submitted by Jan De Luyck */ +UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, + "CITIZEN", + "X1DE-USB", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_SINGLE_LUN), /* Entry needed for flags. Moreover, all devices with this ID use * bulk-only transport, but _some_ falsely report Control/Bulk instead. -- cgit v0.10.2 From 1d614a4b0d2613d83f7bf0978e213ba29aebc44f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 13 Feb 2006 10:15:22 -0500 Subject: [PATCH] USB: unusual_devs.h entry: TrekStor i.Beat A new unusual_devs.h entry (as651). Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6e32615..1d8a739 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -106,6 +106,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Reported by Christian Leber */ +UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100, + "TrekStor", + "i.Beat 115 2.0", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_NOT_LOCKABLE ), + /* Reported by Stefan Werner */ UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, "TrekStor", -- cgit v0.10.2 From 982db2a127b29c9e1f5896d2ba691e84446cc858 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 13 Feb 2006 10:16:04 -0500 Subject: [PATCH] USB: unusual_devs.h entry: iAUDIO M5 Another unusual_devs.h entry (as652). Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1d8a739..7e1cb03 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1098,6 +1098,13 @@ UNUSUAL_DEV( 0x0dda, 0x0301, 0x0012, 0x0012, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Jim McCloskey */ +UNUSUAL_DEV( 0x0e21, 0x0520, 0x0100, 0x0100, + "Cowon Systems", + "iAUDIO M5", + US_SC_DEVICE, US_PR_BULK, NULL, + 0 ), + /* Submitted by Antoine Mairesse */ UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, "USB", -- cgit v0.10.2 From 16f05be7be0bf121491d83bd97337fe179b3b323 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Mon, 13 Feb 2006 15:59:42 -0800 Subject: [PATCH] USB: unusual-devs bugfix The following patch looks good to me. It adds an unusual_devs entry as well as fixing an ordering bug. Please apply. From: Bohdan Linda Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 7e1cb03..e71c5ca 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -134,6 +134,14 @@ UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), #endif +/* Patch submitted by Daniel Drake + * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */ +UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100, + "Neuros Audio", + "USB 2.0 HD 2.5", + US_SC_DEVICE, US_PR_BULK, NULL, + US_FL_NEED_OVERRIDE ), + /* * Pete Zaitcev , from Patrick C. F. Ernzer, bz#162559. * The key does not actually break, but it returns zero sense which @@ -144,13 +152,16 @@ UNUSUAL_DEV( 0x0457, 0x0150, 0x0100, 0x0100, "USB Mass Storage Device", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), -/* Patch submitted by Daniel Drake - * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */ -UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100, - "Neuros Audio", - "USB 2.0 HD 2.5", - US_SC_DEVICE, US_PR_BULK, NULL, - US_FL_NEED_OVERRIDE ), +/* +* Bohdan Linda +* 1GB USB sticks MyFlash High Speed. I have restricted +* the revision to my model only +*/ +UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100, + "USB 2.0", + "Flash Disk", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_NOT_LOCKABLE ), UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, "Rio", -- cgit v0.10.2 From e3efa5a7392e07471b5d0ef7e7cd7ab862f70284 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 5 Feb 2006 23:11:16 +0100 Subject: [PATCH] vt8231: Fix sysfs temperature interface The VT8231 low temperature limits are actually hysteresis temperatures to the high limits. Signed-off-by: Jean Delvare Cc: Roger Lucas Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 3eb08f0..271e9cb 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -437,12 +437,12 @@ static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ show_temp, NULL, offset - 1); \ static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ show_temp_max, set_temp_max, offset - 1); \ -static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ +static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ show_temp_min, set_temp_min, offset - 1) static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL); static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max); -static DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min); +static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min); define_temperature_sysfs(2); define_temperature_sysfs(3); @@ -451,7 +451,7 @@ define_temperature_sysfs(5); define_temperature_sysfs(6); #define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \ - &sensor_dev_attr_temp##id##_min.dev_attr, \ + &sensor_dev_attr_temp##id##_max_hyst.dev_attr, \ &sensor_dev_attr_temp##id##_max.dev_attr } #define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \ &sensor_dev_attr_in##id##_min.dev_attr, \ @@ -464,7 +464,7 @@ struct str_device_attr_table { }; static struct str_device_attr_table cfg_info_temp[] = { - { &dev_attr_temp1_input, &dev_attr_temp1_min, &dev_attr_temp1_max }, + { &dev_attr_temp1_input, &dev_attr_temp1_max_hyst, &dev_attr_temp1_max }, CFG_INFO_TEMP(2), CFG_INFO_TEMP(3), CFG_INFO_TEMP(4), -- cgit v0.10.2 From c7f5d7edd8b3fa4204389efc4c9081cc90a811d2 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 5 Feb 2006 23:13:48 +0100 Subject: [PATCH] w83781d: Use real-time status registers Use the real-time status registers of the Winbond W83782D, W83783S and W83627HF chips, instead of the interrupt status registers. Interrupts cannot be trusted at least for voltage inputs, as they are two-times triggers (as opposed to comparator mode, which we want.) The w83627hf driver was fixed in a similar way some times ago. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 5571148..64c1f8a 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -95,11 +95,16 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); (0x39))) #define W83781D_REG_CONFIG 0x40 + +/* Interrupt status (W83781D, AS99127F) */ #define W83781D_REG_ALARM1 0x41 #define W83781D_REG_ALARM2 0x42 -#define W83781D_REG_ALARM3 0x450 /* not on W83781D */ -#define W83781D_REG_IRQ 0x4C +/* Real-time status (W83782D, W83783S, W83627HF) */ +#define W83782D_REG_ALARM1 0x459 +#define W83782D_REG_ALARM2 0x45A +#define W83782D_REG_ALARM3 0x45B + #define W83781D_REG_BEEP_CONFIG 0x4D #define W83781D_REG_BEEP_INTS1 0x56 #define W83781D_REG_BEEP_INTS2 0x57 @@ -1513,15 +1518,6 @@ w83781d_init_client(struct i2c_client *client) W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); } } - - if (type != w83781d) { - /* enable comparator mode for temp2 and temp3 so - alarm indication will work correctly */ - i = w83781d_read_value(client, W83781D_REG_IRQ); - if (!(i & 0x40)) - w83781d_write_value(client, W83781D_REG_IRQ, - i | 0x40); - } } /* Start monitoring */ @@ -1612,14 +1608,25 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) data->fan_div[1] |= (i >> 4) & 0x04; data->fan_div[2] |= (i >> 5) & 0x04; } - data->alarms = - w83781d_read_value(client, - W83781D_REG_ALARM1) + - (w83781d_read_value(client, W83781D_REG_ALARM2) << 8); if ((data->type == w83782d) || (data->type == w83627hf)) { - data->alarms |= - w83781d_read_value(client, - W83781D_REG_ALARM3) << 16; + data->alarms = w83781d_read_value(client, + W83782D_REG_ALARM1) + | (w83781d_read_value(client, + W83782D_REG_ALARM2) << 8) + | (w83781d_read_value(client, + W83782D_REG_ALARM3) << 16); + } else if (data->type == w83783s) { + data->alarms = w83781d_read_value(client, + W83782D_REG_ALARM1) + | (w83781d_read_value(client, + W83782D_REG_ALARM2) << 8); + } else { + /* No real-time status registers, fall back to + interrupt status registers */ + data->alarms = w83781d_read_value(client, + W83781D_REG_ALARM1) + | (w83781d_read_value(client, + W83781D_REG_ALARM2) << 8); } i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2); data->beep_enable = i >> 7; -- cgit v0.10.2 From a40f0b0f2466483fad94e62177272d6a5711e50a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 5 Feb 2006 23:17:34 +0100 Subject: [PATCH] w83627hf: Document the reset module parameter Document the reset module parameter which was recently added to the w83627hf driver. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf index 5d23776..bbeaba6 100644 --- a/Documentation/hwmon/w83627hf +++ b/Documentation/hwmon/w83627hf @@ -36,6 +36,10 @@ Module Parameters (default is 1) Use 'init=0' to bypass initializing the chip. Try this if your computer crashes when you load the module. +* reset: int + (default is 0) + The driver used to reset the chip on load, but does no more. Use + 'reset=1' to restore the old behavior. Report if you need to do this. Description ----------- -- cgit v0.10.2 From be79c383254cd3eb50953d8c0a7cacdbf6db31c0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 7 Feb 2006 17:53:32 +0100 Subject: [PATCH] it87: Fix oops on removal Fix an oops on it87 module removal when no supported hardware was found. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e87d52c..d7a9401 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -1186,7 +1186,8 @@ static int __init sm_it87_init(void) static void __exit sm_it87_exit(void) { - i2c_isa_del_driver(&it87_isa_driver); + if (isa_address) + i2c_isa_del_driver(&it87_isa_driver); i2c_del_driver(&it87_driver); } -- cgit v0.10.2 From 41d9c98fe76298cebc5907bcebfb2db28017a277 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 8 Feb 2006 20:38:29 +0100 Subject: [PATCH] i2c: Drop outdated probe/remove code in i2c-isa Probe and remove methods are now defined at bus level. No more need to redefine them at driver level in i2c-isa. This lets us get rid of these annoying messages: Driver 'it87-isa' needs updating - please use bus_type methods Thanks to Nicolas Mailhot for reporting the problem and testing the fix. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 9f2ffef..4344ae6 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c @@ -72,16 +72,6 @@ static ssize_t show_adapter_name(struct device *dev, } static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); -static int i2c_isa_device_probe(struct device *dev) -{ - return -ENODEV; -} - -static int i2c_isa_device_remove(struct device *dev) -{ - return 0; -} - /* We implement an interface which resembles i2c_{add,del}_driver, but for i2c-isa drivers. We don't have to remember and handle lists @@ -93,8 +83,6 @@ int i2c_isa_add_driver(struct i2c_driver *driver) /* Add the driver to the list of i2c drivers in the driver core */ driver->driver.bus = &i2c_bus_type; - driver->driver.probe = i2c_isa_device_probe; - driver->driver.remove = i2c_isa_device_remove; res = driver_register(&driver->driver); if (res) return res; -- cgit v0.10.2 From 303794400992b907b7cac0d91788603636c7e0fe Mon Sep 17 00:00:00 2001 From: Gerald Britton Date: Tue, 14 Feb 2006 10:19:04 -0500 Subject: [PATCH] x86: fix oprofile kernel callgraph regression Fix x86 oprofile regression introduced by: commit c34d1b4d165c67b966bca4aba026443d7ff161eb [PATCH] mm: kill check_user_page_readable That commit reorganized tests for the userspace stack walking moving all those tests into dump_backtrace(), however, dump_backtrace() was used for both userspace and kernel stalk walking. The result is typically no recorded callgraph information for kernel samples. Revive the original function as dump_kernel_backtrace() and rename the other to dump_user_backtrace() to avoid future confusion. Signed-off-by: Gerald Britton Apology-from: Hugh Dickins Signed-off-by: Linus Torvalds diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c index acc1813..c049ce4 100644 --- a/arch/i386/oprofile/backtrace.c +++ b/arch/i386/oprofile/backtrace.c @@ -20,7 +20,20 @@ struct frame_head { } __attribute__((packed)); static struct frame_head * -dump_backtrace(struct frame_head * head) +dump_kernel_backtrace(struct frame_head * head) +{ + oprofile_add_trace(head->ret); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (head >= head->ebp) + return NULL; + + return head->ebp; +} + +static struct frame_head * +dump_user_backtrace(struct frame_head * head) { struct frame_head bufhead[2]; @@ -105,10 +118,10 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth) if (!user_mode_vm(regs)) { while (depth-- && valid_kernel_stack(head, regs)) - head = dump_backtrace(head); + head = dump_kernel_backtrace(head); return; } while (depth-- && head) - head = dump_backtrace(head); + head = dump_user_backtrace(head); } -- cgit v0.10.2 From faead26d7a06605add627f29aee73ba654ce11f9 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 14 Feb 2006 10:42:07 -0600 Subject: [PATCH] add scsi_execute_in_process_context() API We have several points in the SCSI stack (primarily for our device functions) where we need to guarantee process context, but (given the place where the last reference was released) we cannot guarantee this. This API gets around the issue by executing the function directly if the caller has process context, but scheduling a workqueue to execute in process context if the caller doesn't have it. Unfortunately, it requires memory allocation in interrupt context, but it's better than what we have previously. The true solution will require a bit of re-engineering, so isn't appropriate for 2.6.16. Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4a60285..4362dcd 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -2248,3 +2249,61 @@ scsi_target_unblock(struct device *dev) device_for_each_child(dev, NULL, target_unblock); } EXPORT_SYMBOL_GPL(scsi_target_unblock); + + +struct work_queue_work { + struct work_struct work; + void (*fn)(void *); + void *data; +}; + +static void execute_in_process_context_work(void *data) +{ + void (*fn)(void *data); + struct work_queue_work *wqw = data; + + fn = wqw->fn; + data = wqw->data; + + kfree(wqw); + + fn(data); +} + +/** + * scsi_execute_in_process_context - reliably execute the routine with user context + * @fn: the function to execute + * @data: data to pass to the function + * + * Executes the function immediately if process context is available, + * otherwise schedules the function for delayed execution. + * + * Returns: 0 - function was executed + * 1 - function was scheduled for execution + * <0 - error + */ +int scsi_execute_in_process_context(void (*fn)(void *data), void *data) +{ + struct work_queue_work *wqw; + + if (!in_interrupt()) { + fn(data); + return 0; + } + + wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC); + + if (unlikely(!wqw)) { + printk(KERN_ERR "Failed to allocate memory\n"); + WARN_ON(1); + return -ENOMEM; + } + + INIT_WORK(&wqw->work, execute_in_process_context_work, wqw); + wqw->fn = fn; + wqw->data = data; + schedule_work(&wqw->work); + + return 1; +} +EXPORT_SYMBOL_GPL(scsi_execute_in_process_context); diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index c60b8ff..9c33125 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -433,4 +433,6 @@ struct scsi_lun { /* Used to obtain the PCI location of a device */ #define SCSI_IOCTL_GET_PCI 0x5387 +int scsi_execute_in_process_context(void (*fn)(void *data), void *data); + #endif /* _SCSI_SCSI_H */ -- cgit v0.10.2 From 65110b2168950a19cc78b5027ed18cb811fbdae8 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 14 Feb 2006 10:48:46 -0600 Subject: [SCSI] fix wrong context bugs in SCSI There's a bug in releasing scsi_device where the release function actually frees the block queue. However, the block queue release calls flush_work(), which requires process context (the scsi_device structure may release from irq context). Update the release function to invoke via the execute_in_process_context() API. Also clean up the scsi_target structure releasing via this API. Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 752fb5d..5acb83c 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -387,19 +387,12 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, return found_target; } -struct work_queue_wrapper { - struct work_struct work; - struct scsi_target *starget; -}; - -static void scsi_target_reap_work(void *data) { - struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; - struct scsi_target *starget = wqw->starget; +static void scsi_target_reap_usercontext(void *data) +{ + struct scsi_target *starget = data; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); unsigned long flags; - kfree(wqw); - spin_lock_irqsave(shost->host_lock, flags); if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { @@ -428,18 +421,7 @@ static void scsi_target_reap_work(void *data) { */ void scsi_target_reap(struct scsi_target *starget) { - struct work_queue_wrapper *wqw = - kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); - - if (!wqw) { - starget_printk(KERN_ERR, starget, - "Failed to allocate memory in scsi_reap_target()\n"); - return; - } - - INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); - wqw->starget = starget; - schedule_work(&wqw->work); + scsi_execute_in_process_context(scsi_target_reap_usercontext, starget); } /** diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index a77b32d..902a5de 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -217,8 +217,9 @@ 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) +static void scsi_device_dev_release_usercontext(void *data) { + struct device *dev = data; struct scsi_device *sdev; struct device *parent; struct scsi_target *starget; @@ -237,6 +238,7 @@ static void scsi_device_dev_release(struct device *dev) if (sdev->request_queue) { sdev->request_queue->queuedata = NULL; + /* user context needed to free queue */ scsi_free_queue(sdev->request_queue); /* temporary expedient, try to catch use of queue lock * after free of sdev */ @@ -252,6 +254,11 @@ static void scsi_device_dev_release(struct device *dev) put_device(parent); } +static void scsi_device_dev_release(struct device *dev) +{ + scsi_execute_in_process_context(scsi_device_dev_release_usercontext, dev); +} + static struct class sdev_class = { .name = "scsi_device", .release = scsi_device_cls_release, -- cgit v0.10.2 From 5552c28f6937d2a2b873d06c6d09b96204722dd0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 14 Feb 2006 17:50:54 +0000 Subject: [PATCH] Fix locking error in esp Noted by Al Viro. Also remove unused tmp_buf Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 57539d8..09dc4b0 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c @@ -150,17 +150,6 @@ static void rs_wait_until_sent(struct tty_struct *, int); /* Standard COM flags (except for COM4, because of the 8514 problem) */ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the memcpy_fromfs blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; - static inline int serial_paranoia_check(struct esp_struct *info, char *name, const char *routine) { @@ -1267,7 +1256,7 @@ static int rs_write(struct tty_struct * tty, if (serial_paranoia_check(info, tty->name, "rs_write")) return 0; - if (!tty || !info->xmit_buf || !tmp_buf) + if (!tty || !info->xmit_buf) return 0; while (1) { @@ -2291,11 +2280,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp) tty->driver_data = info; info->tty = tty; - if (!tmp_buf) { - tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL); - if (!tmp_buf) - return -ENOMEM; - } + spin_unlock_irqrestore(&info->lock, flags); /* * Start up serial port @@ -2602,9 +2587,6 @@ static void __exit espserial_exit(void) free_pages((unsigned long)dma_buffer, get_order(DMA_BUFFER_SZ)); - if (tmp_buf) - free_page((unsigned long)tmp_buf); - while (free_pio_buf) { pio_buf = free_pio_buf->next; kfree(free_pio_buf); -- cgit v0.10.2 From f32ec77b421ee15bf5a42082b60679e997c07993 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 28 Nov 2005 13:10:54 +0000 Subject: [MIPS] RM200: Give RM200 it's own timex.h. So we can get rid of config.h and the #ifdef crapola in the generic timex.h. Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/mach-generic/timex.h b/include/asm-mips/mach-generic/timex.h index c6a2e5f..48b4cfa 100644 --- a/include/asm-mips/mach-generic/timex.h +++ b/include/asm-mips/mach-generic/timex.h @@ -3,20 +3,11 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003 by Ralf Baechle + * Copyright (C) 2003, 2005 by Ralf Baechle */ #ifndef __ASM_MACH_GENERIC_TIMEX_H #define __ASM_MACH_GENERIC_TIMEX_H -#include - -/* - * Last remaining user of the i8254 PIC, will be converted, too ... - */ -#ifdef CONFIG_SNI_RM200_PCI -#define CLOCK_TICK_RATE 1193182 -#else #define CLOCK_TICK_RATE 500000 -#endif #endif /* __ASM_MACH_GENERIC_TIMEX_H */ diff --git a/include/asm-mips/mach-rm200/timex.h b/include/asm-mips/mach-rm200/timex.h new file mode 100644 index 0000000..11ff6cb --- /dev/null +++ b/include/asm-mips/mach-rm200/timex.h @@ -0,0 +1,13 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003, 2005 by Ralf Baechle + */ +#ifndef __ASM_MACH_RM200_TIMEX_H +#define __ASM_MACH_RM200_TIMEX_H + +#define CLOCK_TICK_RATE 1193182 + +#endif /* __ASM_MACH_RM200_TIMEX_H */ -- cgit v0.10.2 From a3c9dc38313d05e4254c100e86af205cf33e8cd3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 14 Feb 2006 19:13:23 +0000 Subject: [MIPS] Update docs to reflect the latest status of the Alchemy IDE driver. Signed-off-by: Ralf Baechle diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README index a7e4c4e..afb31c1 100644 --- a/Documentation/mips/AU1xxx_IDE.README +++ b/Documentation/mips/AU1xxx_IDE.README @@ -95,11 +95,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDE_AU1XXX=y CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y -CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON=y CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_AUTO=y +Also define 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to enable +the burst support on DBDMA controller. + If the used system need the USB support enable the following kernel configs for high IDE to USB throughput. @@ -115,6 +117,8 @@ CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_AUTO=y +Also undefine 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to +disable the burst support on DBDMA controller. ADD NEW HARD DISC TO WHITE OR BLACK LIST ---------------------------------------- -- cgit v0.10.2 From 359bbd42a5a205234d5943571fc7bf946967ee59 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 9 Feb 2006 12:13:28 +0000 Subject: [MIPS] Fold non-__mips64 case into CONFIG_32BIT case. Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index e7ff9b1..769305d 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -1184,10 +1184,8 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGACTION -# ifndef __mips64 -# define __ARCH_WANT_STAT64 -# endif # ifdef CONFIG_32BIT +# define __ARCH_WANT_STAT64 # define __ARCH_WANT_SYS_TIME # endif # ifdef CONFIG_MIPS32_O32 -- cgit v0.10.2 From 1bdfd0d9632f0254a4fc01d17c9933ae6107dec4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 9 Feb 2006 12:26:35 +0000 Subject: [MIPS] Remove commented out function prom_build_cpu_map. Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c index 794a1c3..186f5de 100644 --- a/arch/mips/kernel/smp_mt.c +++ b/arch/mips/kernel/smp_mt.c @@ -102,35 +102,6 @@ void __init sanitize_tlb_entries(void) clear_c0_mvpcontrol(MVPCONTROL_VPC); } -#if 0 -/* - * Use c0_MVPConf0 to find out how many CPUs are available, setting up - * phys_cpu_present_map and the logical/physical mappings. - */ -void __init prom_build_cpu_map(void) -{ - int i, num, ncpus; - - cpus_clear(phys_cpu_present_map); - - /* assume we boot on cpu 0.... */ - cpu_set(0, phys_cpu_present_map); - __cpu_number_map[0] = 0; - __cpu_logical_map[0] = 0; - - if (cpu_has_mipsmt) { - ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1; - for (i=1, num=0; i< NR_CPUS && i Date: Wed, 8 Feb 2006 01:48:03 +0900 Subject: [MIPS] Rewrite get_wchan and its helper functions using kallsyms_lookup. Implement get_wchan() and frame_info_init() using kallsyms_lookup(). This fixes problem with static sched/lock functions and mfinfo[] maintenance issue. If CONFIG_KALLSYMS was disabled, get_wchan() just returns thread_saved_pc() value. Also unwind stackframe based on "addiu sp,-imm" analysis instead of frame pointer. This fixes problem with functions compiled without -fomit-frame-pointer. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 5232fc7..092679c 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -272,46 +273,19 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) static struct mips_frame_info { void *func; - int omit_fp; /* compiled without fno-omit-frame-pointer */ - int frame_offset; + unsigned long func_size; + int frame_size; int pc_offset; -} schedule_frame, mfinfo[] = { - { schedule, 0 }, /* must be first */ - /* arch/mips/kernel/semaphore.c */ - { __down, 1 }, - { __down_interruptible, 1 }, - /* kernel/sched.c */ -#ifdef CONFIG_PREEMPT - { preempt_schedule, 0 }, -#endif - { wait_for_completion, 0 }, - { interruptible_sleep_on, 0 }, - { interruptible_sleep_on_timeout, 0 }, - { sleep_on, 0 }, - { sleep_on_timeout, 0 }, - { yield, 0 }, - { io_schedule, 0 }, - { io_schedule_timeout, 0 }, -#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) - { __preempt_spin_lock, 0 }, - { __preempt_write_lock, 0 }, -#endif - /* kernel/timer.c */ - { schedule_timeout, 1 }, -/* { nanosleep_restart, 1 }, */ - /* lib/rwsem-spinlock.c */ - { __down_read, 1 }, - { __down_write, 1 }, -}; +} *schedule_frame, mfinfo[64]; +static int mfinfo_num; -static int mips_frame_info_initialized; static int __init get_frame_info(struct mips_frame_info *info) { int i; void *func = info->func; union mips_instruction *ip = (union mips_instruction *)func; info->pc_offset = -1; - info->frame_offset = info->omit_fp ? 0 : -1; + info->frame_size = 0; for (i = 0; i < 128; i++, ip++) { /* if jal, jalr, jr, stop. */ if (ip->j_format.opcode == jal_op || @@ -320,6 +294,23 @@ static int __init get_frame_info(struct mips_frame_info *info) ip->r_format.func == jr_op))) break; + if (info->func_size && i >= info->func_size / 4) + break; + if ( +#ifdef CONFIG_32BIT + ip->i_format.opcode == addiu_op && +#endif +#ifdef CONFIG_64BIT + ip->i_format.opcode == daddiu_op && +#endif + ip->i_format.rs == 29 && + ip->i_format.rt == 29) { + /* addiu/daddiu sp,sp,-imm */ + if (info->frame_size) + continue; + info->frame_size = - ip->i_format.simmediate; + } + if ( #ifdef CONFIG_32BIT ip->i_format.opcode == sw_op && @@ -327,31 +318,20 @@ static int __init get_frame_info(struct mips_frame_info *info) #ifdef CONFIG_64BIT ip->i_format.opcode == sd_op && #endif - ip->i_format.rs == 29) - { + ip->i_format.rs == 29 && + ip->i_format.rt == 31) { /* sw / sd $ra, offset($sp) */ - if (ip->i_format.rt == 31) { - if (info->pc_offset != -1) - continue; - info->pc_offset = - ip->i_format.simmediate / sizeof(long); - } - /* sw / sd $s8, offset($sp) */ - if (ip->i_format.rt == 30) { -//#if 0 /* gcc 3.4 does aggressive optimization... */ - if (info->frame_offset != -1) - continue; -//#endif - info->frame_offset = - ip->i_format.simmediate / sizeof(long); - } + if (info->pc_offset != -1) + continue; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); } } - if (info->pc_offset == -1 || info->frame_offset == -1) { - printk("Can't analyze prologue code at %p\n", func); + if (info->pc_offset == -1 || info->frame_size == 0) { + if (func == schedule) + printk("Can't analyze prologue code at %p\n", func); info->pc_offset = -1; - info->frame_offset = -1; - return -1; + info->frame_size = 0; } return 0; @@ -359,25 +339,36 @@ static int __init get_frame_info(struct mips_frame_info *info) static int __init frame_info_init(void) { - int i, found; - for (i = 0; i < ARRAY_SIZE(mfinfo); i++) - if (get_frame_info(&mfinfo[i])) - return -1; - schedule_frame = mfinfo[0]; - /* bubble sort */ - do { - struct mips_frame_info tmp; - found = 0; - for (i = 1; i < ARRAY_SIZE(mfinfo); i++) { - if (mfinfo[i-1].func > mfinfo[i].func) { - tmp = mfinfo[i]; - mfinfo[i] = mfinfo[i-1]; - mfinfo[i-1] = tmp; - found = 1; - } - } - } while (found); - mips_frame_info_initialized = 1; + int i; +#ifdef CONFIG_KALLSYMS + char *modname; + char namebuf[KSYM_NAME_LEN + 1]; + unsigned long start, size, ofs; + extern char __sched_text_start[], __sched_text_end[]; + extern char __lock_text_start[], __lock_text_end[]; + + start = (unsigned long)__sched_text_start; + for (i = 0; i < ARRAY_SIZE(mfinfo); i++) { + if (start == (unsigned long)schedule) + schedule_frame = &mfinfo[i]; + if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf)) + break; + mfinfo[i].func = (void *)(start + ofs); + mfinfo[i].func_size = size; + start += size - ofs; + if (start >= (unsigned long)__lock_text_end) + break; + if (start == (unsigned long)__sched_text_end) + start = (unsigned long)__lock_text_start; + } +#else + mfinfo[0].func = schedule; + schedule_frame = &mfinfo[0]; +#endif + for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) + get_frame_info(&mfinfo[i]); + + mfinfo_num = i; return 0; } @@ -394,47 +385,52 @@ unsigned long thread_saved_pc(struct task_struct *tsk) if (t->reg31 == (unsigned long) ret_from_fork) return t->reg31; - if (schedule_frame.pc_offset < 0) + if (!schedule_frame || schedule_frame->pc_offset < 0) return 0; - return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; + return ((unsigned long *)t->reg29)[schedule_frame->pc_offset]; } /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ unsigned long get_wchan(struct task_struct *p) { unsigned long stack_page; - unsigned long frame, pc; + unsigned long pc; +#ifdef CONFIG_KALLSYMS + unsigned long frame; +#endif if (!p || p == current || p->state == TASK_RUNNING) return 0; stack_page = (unsigned long)task_stack_page(p); - if (!stack_page || !mips_frame_info_initialized) + if (!stack_page || !mfinfo_num) return 0; pc = thread_saved_pc(p); +#ifdef CONFIG_KALLSYMS if (!in_sched_functions(pc)) return pc; - frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + frame = p->thread.reg29 + schedule_frame->frame_size; do { int i; if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) return 0; - for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) { + for (i = mfinfo_num - 1; i >= 0; i--) { if (pc >= (unsigned long) mfinfo[i].func) break; } if (i < 0) break; - if (mfinfo[i].omit_fp) - break; pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; - frame = ((unsigned long *)frame)[mfinfo[i].frame_offset]; + if (!mfinfo[i].frame_size) + break; + frame += mfinfo[i].frame_size; } while (in_sched_functions(pc)); +#endif return pc; } -- cgit v0.10.2 From 41700e73995d6c814932cb55e12525bd34be1ca5 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 10 Feb 2006 00:39:06 +0900 Subject: [MIPS] Add protected_blast_icache_range, blast_icache_range, etc. Add blast_xxx_range(), protected_blast_xxx_range() etc. for common use. They are built by __BUILD_BLAST_CACHE_RANGE(). Use protected_cache_op() macro for various protected_ routines. Output code should be logically same. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index e51c38c..1b71d91 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -471,61 +471,29 @@ struct flush_icache_range_args { static inline void local_r4k_flush_icache_range(void *args) { struct flush_icache_range_args *fir_args = args; - unsigned long dc_lsize = cpu_dcache_line_size(); - unsigned long ic_lsize = cpu_icache_line_size(); - unsigned long sc_lsize = cpu_scache_line_size(); unsigned long start = fir_args->start; unsigned long end = fir_args->end; - unsigned long addr, aend; if (!cpu_has_ic_fills_f_dc) { if (end - start > dcache_size) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; - addr = start & ~(dc_lsize - 1); - aend = (end - 1) & ~(dc_lsize - 1); - - while (1) { - /* Hit_Writeback_Inv_D */ - protected_writeback_dcache_line(addr); - if (addr == aend) - break; - addr += dc_lsize; - } + protected_blast_dcache_range(start, end); } if (!cpu_icache_snoops_remote_store) { - if (end - start > scache_size) { + if (end - start > scache_size) r4k_blast_scache(); - } else { - addr = start & ~(sc_lsize - 1); - aend = (end - 1) & ~(sc_lsize - 1); - - while (1) { - /* Hit_Writeback_Inv_SD */ - protected_writeback_scache_line(addr); - if (addr == aend) - break; - addr += sc_lsize; - } - } + else + protected_blast_scache_range(start, end); } } if (end - start > icache_size) r4k_blast_icache(); - else { - addr = start & ~(ic_lsize - 1); - aend = (end - 1) & ~(ic_lsize - 1); - while (1) { - /* Hit_Invalidate_I */ - protected_flush_icache_line(addr); - if (addr == aend) - break; - addr += ic_lsize; - } - } + else + protected_blast_icache_range(start, end); } static void r4k_flush_icache_range(unsigned long start, unsigned long end) @@ -619,27 +587,14 @@ static void r4k_flush_icache_page(struct vm_area_struct *vma, static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) { - unsigned long end, a; - /* Catch bad driver code */ BUG_ON(size == 0); if (cpu_has_subset_pcaches) { - unsigned long sc_lsize = cpu_scache_line_size(); - - if (size >= scache_size) { + if (size >= scache_size) r4k_blast_scache(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size - 1) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) - break; - a += sc_lsize; - } + else + blast_scache_range(addr, addr + size); return; } @@ -651,17 +606,8 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) if (size >= dcache_size) { r4k_blast_dcache(); } else { - unsigned long dc_lsize = cpu_dcache_line_size(); - R4600_HIT_CACHEOP_WAR_IMPL; - a = addr & ~(dc_lsize - 1); - end = (addr + size - 1) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) - break; - a += dc_lsize; - } + blast_dcache_range(addr, addr + size); } bc_wback_inv(addr, size); @@ -669,44 +615,22 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) { - unsigned long end, a; - /* Catch bad driver code */ BUG_ON(size == 0); if (cpu_has_subset_pcaches) { - unsigned long sc_lsize = cpu_scache_line_size(); - - if (size >= scache_size) { + if (size >= scache_size) r4k_blast_scache(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size - 1) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) - break; - a += sc_lsize; - } + else + blast_scache_range(addr, addr + size); return; } if (size >= dcache_size) { r4k_blast_dcache(); } else { - unsigned long dc_lsize = cpu_dcache_line_size(); - R4600_HIT_CACHEOP_WAR_IMPL; - a = addr & ~(dc_lsize - 1); - end = (addr + size - 1) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) - break; - a += dc_lsize; - } + blast_dcache_range(addr, addr + size); } bc_inv(addr, size); diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 0a97a94..7c572be 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -44,8 +44,6 @@ __asm__ __volatile__( \ /* TX39H-style cache flush routines. */ static void tx39h_flush_icache_all(void) { - unsigned long start = KSEG0; - unsigned long end = (start + icache_size); unsigned long flags, config; /* disable icache (set ICE#) */ @@ -53,33 +51,18 @@ static void tx39h_flush_icache_all(void) config = read_c0_conf(); write_c0_conf(config & ~TX39_CONF_ICE); TX39_STOP_STREAMING(); - - /* invalidate icache */ - while (start < end) { - cache16_unroll32(start, Index_Invalidate_I); - start += 0x200; - } - + blast_icache16(); write_c0_conf(config); local_irq_restore(flags); } static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) { - unsigned long end, a; - unsigned long dc_lsize = current_cpu_data.dcache.linesz; - /* Catch bad driver code */ BUG_ON(size == 0); iob(); - a = addr & ~(dc_lsize - 1); - end = (addr + size - 1) & ~(dc_lsize - 1); - while (1) { - invalidate_dcache_line(a); /* Hit_Invalidate_D */ - if (a == end) break; - a += dc_lsize; - } + blast_inv_dcache_range(addr, addr + size); } @@ -241,42 +224,21 @@ static void tx39_flush_data_cache_page(unsigned long addr) static void tx39_flush_icache_range(unsigned long start, unsigned long end) { - unsigned long dc_lsize = current_cpu_data.dcache.linesz; - unsigned long addr, aend; - if (end - start > dcache_size) tx39_blast_dcache(); - else { - addr = start & ~(dc_lsize - 1); - aend = (end - 1) & ~(dc_lsize - 1); - - while (1) { - /* Hit_Writeback_Inv_D */ - protected_writeback_dcache_line(addr); - if (addr == aend) - break; - addr += dc_lsize; - } - } + else + protected_blast_dcache_range(start, end); if (end - start > icache_size) tx39_blast_icache(); else { unsigned long flags, config; - addr = start & ~(dc_lsize - 1); - aend = (end - 1) & ~(dc_lsize - 1); /* disable icache (set ICE#) */ local_irq_save(flags); config = read_c0_conf(); write_c0_conf(config & ~TX39_CONF_ICE); TX39_STOP_STREAMING(); - while (1) { - /* Hit_Invalidate_I */ - protected_flush_icache_line(addr); - if (addr == aend) - break; - addr += dc_lsize; - } + protected_blast_icache_range(start, end); write_c0_conf(config); local_irq_restore(flags); } @@ -311,7 +273,7 @@ static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) { - unsigned long end, a; + unsigned long end; if (((size | addr) & (PAGE_SIZE - 1)) == 0) { end = addr + size; @@ -322,20 +284,13 @@ static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) } else if (size > dcache_size) { tx39_blast_dcache(); } else { - unsigned long dc_lsize = current_cpu_data.dcache.linesz; - a = addr & ~(dc_lsize - 1); - end = (addr + size - 1) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } + blast_dcache_range(addr, addr + size); } } static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) { - unsigned long end, a; + unsigned long end; if (((size | addr) & (PAGE_SIZE - 1)) == 0) { end = addr + size; @@ -346,14 +301,7 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) } else if (size > dcache_size) { tx39_blast_dcache(); } else { - unsigned long dc_lsize = current_cpu_data.dcache.linesz; - a = addr & ~(dc_lsize - 1); - end = (addr + size - 1) & ~(dc_lsize - 1); - while (1) { - invalidate_dcache_line(a); /* Hit_Invalidate_D */ - if (a == end) break; - a += dc_lsize; - } + blast_inv_dcache_range(addr, addr + size); } } diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index cc53196..9632c27 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h @@ -14,6 +14,7 @@ #include #include +#include /* * This macro return a properly sign-extended address suitable as base address @@ -78,22 +79,25 @@ static inline void flush_scache_line(unsigned long addr) cache_op(Hit_Writeback_Inv_SD, addr); } +#define protected_cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + "1: cache %0, (%1) \n" \ + "2: .set pop \n" \ + " .section __ex_table,\"a\" \n" \ + " "STR(PTR)" 1b, 2b \n" \ + " .previous" \ + : \ + : "i" (op), "r" (addr)) + /* * The next two are for badland addresses like signal trampolines. */ static inline void protected_flush_icache_line(unsigned long addr) { - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips3 \n" - "1: cache %0, (%1) \n" - "2: .set pop \n" - " .section __ex_table,\"a\" \n" - " "STR(PTR)" 1b, 2b \n" - " .previous" - : - : "i" (Hit_Invalidate_I), "r" (addr)); + protected_cache_op(Hit_Invalidate_I, addr); } /* @@ -104,32 +108,12 @@ static inline void protected_flush_icache_line(unsigned long addr) */ static inline void protected_writeback_dcache_line(unsigned long addr) { - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips3 \n" - "1: cache %0, (%1) \n" - "2: .set pop \n" - " .section __ex_table,\"a\" \n" - " "STR(PTR)" 1b, 2b \n" - " .previous" - : - : "i" (Hit_Writeback_Inv_D), "r" (addr)); + protected_cache_op(Hit_Writeback_Inv_D, addr); } static inline void protected_writeback_scache_line(unsigned long addr) { - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips3 \n" - "1: cache %0, (%1) \n" - "2: .set pop \n" - " .section __ex_table,\"a\" \n" - " "STR(PTR)" 1b, 2b \n" - " .previous" - : - : "i" (Hit_Writeback_Inv_SD), "r" (addr)); + protected_cache_op(Hit_Writeback_Inv_SD, addr); } /* @@ -295,4 +279,28 @@ __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) +/* build blast_xxx_range, protected_blast_xxx_range */ +#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ +static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ + unsigned long end) \ +{ \ + unsigned long lsize = cpu_##desc##_line_size(); \ + unsigned long addr = start & ~(lsize - 1); \ + unsigned long aend = (end - 1) & ~(lsize - 1); \ + while (1) { \ + prot##cache_op(hitop, addr); \ + if (addr == aend) \ + break; \ + addr += lsize; \ + } \ +} + +__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) +__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_) +__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_) +__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) +__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) +/* blast_inv_dcache_range */ +__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) + #endif /* _ASM_R4KCACHE_H */ -- cgit v0.10.2 From 3218357c94af92478ef39163163a81e654385320 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 10 Feb 2006 01:31:24 +0000 Subject: [MIPS] More uaccess.h fixes with gcc >= 4.0.1. From Richard Sandiford : This patch caused a miscompilation of the restore_gp_regs() block in restore_sigcontext(). This was in a 32-bit kernel compiled with GCC CVS head. restore_gp_regs() copies 64-bit user fields into 32-bit variables, and in this combination, the new __get_user_asm_ll32() clobbers too many registers. It says: /* * Get a long long 64 using 32 bit registers. */ { \ __asm__ __volatile__( \ "1: lw %1, (%3) \n" \ "2: lw %D1, 4(%3) \n" \ " move %0, $0 \n" \ "3: .section .fixup,\"ax\" \n" \ "4: li %0, %4 \n" \ " move %1, $0 \n" \ " move %D1, $0 \n" \ " j 3b \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " " __UA_ADDR " 1b, 4b \n" \ " " __UA_ADDR " 2b, 4b \n" \ " .previous \n" \ : "=r" (__gu_err), "=&r" (val) \ : "0" (0), "r" (addr), "i" (-EFAULT)); \ } and this requires val (%1) to be a 64-bit value. In the case I saw, gcc was using $3 for the 32-bit val, and wasn't expecting $4 to be clobbered. Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h index 91d813a..7a553e9 100644 --- a/include/asm-mips/uaccess.h +++ b/include/asm-mips/uaccess.h @@ -266,6 +266,8 @@ do { \ */ #define __get_user_asm_ll32(val, addr) \ { \ + unsigned long long __gu_tmp; \ + \ __asm__ __volatile__( \ "1: lw %1, (%3) \n" \ "2: lw %D1, 4(%3) \n" \ @@ -280,8 +282,9 @@ do { \ " " __UA_ADDR " 1b, 4b \n" \ " " __UA_ADDR " 2b, 4b \n" \ " .previous \n" \ - : "=r" (__gu_err), "=&r" (val) \ + : "=r" (__gu_err), "=&r" (__gu_tmp) \ : "0" (0), "r" (addr), "i" (-EFAULT)); \ + (val) = __gu_tmp; \ } /* -- cgit v0.10.2 From fbb6b3a4ac0ccf12a97c98881d9d873d6dc26fe5 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 10 Feb 2006 14:13:08 +0000 Subject: [MIPS] Get rid of kludgery needed to keep stdargs of old compilers working. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6a57407..38c0f336 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -94,7 +94,6 @@ endif # machines may also. Since BFD is incredibly buggy with respect to # crossformat linking we rely on the elf2ecoff tool for format conversion. # -cflags-y += -I $(TOPDIR)/include/asm/gcc cflags-y += -G 0 -mno-abicalls -fno-pic -pipe LDFLAGS_vmlinux += -G 0 -static -n -nostdlib MODFLAGS += -mlong-calls diff --git a/include/asm-mips/gcc/sgidefs.h b/include/asm-mips/gcc/sgidefs.h deleted file mode 100644 index 0599437..0000000 --- a/include/asm-mips/gcc/sgidefs.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * include/sgidefs.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996 by Ralf Baechle - * - * This file is here to satisfy GCC's expectations. - */ -#ifndef __SGIDEFS_H -#define __SGIDEFS_H - -#include - -#endif /* __SGIDEFS_H */ -- cgit v0.10.2 From fdc9bb16d3e16f674e52aa69306df5732d7f951b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 10 Feb 2006 14:25:16 +0000 Subject: [MIPS] MT: Fix c0 back-to-back hazard. Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c index 186f5de..184fd46 100644 --- a/arch/mips/kernel/smp_mt.c +++ b/arch/mips/kernel/smp_mt.c @@ -68,6 +68,8 @@ void __init sanitize_tlb_entries(void) set_c0_mvpcontrol(MVPCONTROL_VPC); + back_to_back_c0_hazard(); + /* Disable TLB sharing */ clear_c0_mvpcontrol(MVPCONTROL_STLB); -- cgit v0.10.2 From 74a96d943ac96ce607a841a74ff0f84eeb0c3343 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 10 Feb 2006 16:03:47 +0000 Subject: [MIPS] MT: Propagate config7 into VPE. Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c index 184fd46..c930364 100644 --- a/arch/mips/kernel/smp_mt.c +++ b/arch/mips/kernel/smp_mt.c @@ -195,6 +195,9 @@ void prom_prepare_cpus(unsigned int max_cpus) /* set config to be the same as vpe0, particularly kseg0 coherency alg */ write_vpe_c0_config( read_c0_config()); + + /* Propagate Config7 */ + write_vpe_c0_config7(read_c0_config7()); } } -- cgit v0.10.2 From 387a154d0db113690ce85185a003e39e7c87009e Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Fri, 10 Feb 2006 17:36:27 +0100 Subject: [MIPS] RM9000: Fix buggy I-cache workaround. Signed-off-by: Thomas Koeller Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 0fbc492..36bfc25 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h @@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) sp = current->sas_ss_sp + current->sas_ss_size; - return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); + return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK)); } static inline int install_sigtramp(unsigned int __user *tramp, -- cgit v0.10.2 From 9cf8ff96447f995d5ea18ec9f25dc8dae26501a2 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 13 Feb 2006 09:15:49 +0000 Subject: [MIPS] Fix CPU type bitmasks for MIPS III, IV and V. Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 934e063..818b9a9 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -204,9 +204,9 @@ */ #define MIPS_CPU_ISA_I 0x00000001 #define MIPS_CPU_ISA_II 0x00000002 -#define MIPS_CPU_ISA_III 0x00000003 -#define MIPS_CPU_ISA_IV 0x00000004 -#define MIPS_CPU_ISA_V 0x00000005 +#define MIPS_CPU_ISA_III 0x00000004 +#define MIPS_CPU_ISA_IV 0x00000008 +#define MIPS_CPU_ISA_V 0x00000010 #define MIPS_CPU_ISA_M32R1 0x00000020 #define MIPS_CPU_ISA_M32R2 0x00000040 #define MIPS_CPU_ISA_M64R1 0x00000080 -- cgit v0.10.2 From 4cbf8767902c578481ff3df366c77d24fe68fd26 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 14 Feb 2006 22:40:45 +0900 Subject: [MIPS] Fix typo in _sys32_rt_sigreturn and _sysn32_rt_sigreturn. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index da3271e..8a8b8dd 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -537,7 +537,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) /* The ucontext contains a stack32_t, so we must convert! */ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) goto badframe; - st.ss_size = (long) sp; + st.ss_sp = (void *)(long) sp; if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) goto badframe; if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 384fc4a..5a37760 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -108,7 +108,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) /* The ucontext contains a stack32_t, so we must convert! */ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) goto badframe; - st.ss_size = (long) sp; + st.ss_sp = (void *)(long) sp; if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) goto badframe; if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) -- cgit v0.10.2 From 69aa234b918c0d9bc4a20cd6d4453aaa3418f457 Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Tue, 14 Feb 2006 15:01:11 -0800 Subject: [IA64] Dont set NR_CPUS for cpu_possible_map when CPU hotplug is enabled. Do not set cpu_possible_map for NR_CPUS when ACPI_CONFIG_HOTPLUG_CPU is set. Signed-off-by: Ashok Raj Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 8f44e7d..b681ef3 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -129,7 +129,7 @@ DEFINE_PER_CPU(int, cpu_state); /* Bitmasks of currently online, and possible CPUs */ cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); -cpumask_t cpu_possible_map; +cpumask_t cpu_possible_map = CPU_MASK_NONE; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; @@ -506,9 +506,6 @@ smp_build_cpu_map (void) for (cpu = 0; cpu < NR_CPUS; cpu++) { ia64_cpu_to_sapicid[cpu] = -1; -#ifdef CONFIG_HOTPLUG_CPU - cpu_set(cpu, cpu_possible_map); -#endif } ia64_cpu_to_sapicid[0] = boot_cpu_id; -- cgit v0.10.2 From a6b14fa6fdc01ab3519c2729624f808677539b59 Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Tue, 14 Feb 2006 15:01:12 -0800 Subject: [IA64] Count disabled cpus as potential hot-pluggable CPUs Have a facility to account for potentially hot-pluggable CPUs. ACPI doesnt give a determinstic method to find hot-pluggable CPUs. Hence we use 2 methods to assist. - BIOS can mark potentially hot-pluggable CPUs as disabled in the MADT tables. - User can specify the number of hot-pluggable CPUs via parameter additional_cpus=X The option is enabled only if ACPI_CONFIG_HOTPLUG_CPU=y which enables the physical hotplug option. Without which user can still use logical onlining and offlining of CPUs by enabling CONFIG_HOTPLUG_CPU=y Adds more bits to cpu_possible_map for potentially hot-pluggable cpus. Signed-off-by: Ashok Raj Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index d2702c4..34795ed 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -761,6 +761,62 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid) return (0); } +int additional_cpus __initdata = -1; + +static __init int setup_additional_cpus(char *s) +{ + if (s) + additional_cpus = simple_strtol(s, NULL, 0); + + return 0; +} + +early_param("additional_cpus", setup_additional_cpus); + +/* + * cpu_possible_map should be static, it cannot change as cpu's + * are onlined, or offlined. The reason is per-cpu data-structures + * are allocated by some modules at init time, and dont expect to + * do this dynamically on cpu arrival/departure. + * cpu_present_map on the other hand can change dynamically. + * In case when cpu_hotplug is not compiled, then we resort to current + * behaviour, which is cpu_possible == cpu_present. + * - Ashok Raj + * + * Three ways to find out the number of additional hotplug CPUs: + * - If the BIOS specified disabled CPUs in ACPI/mptables use that. + * - The user can overwrite it with additional_cpus=NUM + * - Otherwise don't reserve additional CPUs. + */ +__init void prefill_possible_map(void) +{ + int i; + int possible, disabled_cpus; + + disabled_cpus = total_cpus - available_cpus; + if (additional_cpus == -1) { + if (disabled_cpus > 0) { + possible = total_cpus; + additional_cpus = disabled_cpus; + } + else { + possible = available_cpus; + additional_cpus = 0; + } + } else { + possible = available_cpus + additional_cpus; + } + if (possible > NR_CPUS) + possible = NR_CPUS; + + printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", + possible, + max_t(int, additional_cpus, 0)); + + for (i = 0; i < possible; i++) + cpu_set(i, cpu_possible_map); +} + int acpi_map_lsapic(acpi_handle handle, int *pcpu) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 35f7835..3258e09 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -430,6 +430,7 @@ setup_arch (char **cmdline_p) if (early_console_setup(*cmdline_p) == 0) mark_bsp_online(); + parse_early_param(); #ifdef CONFIG_ACPI /* Initialize the ACPI boot-time table parser */ acpi_table_init(); @@ -688,6 +689,9 @@ void setup_per_cpu_areas (void) { /* start_kernel() requires this... */ +#ifdef CONFIG_ACPI_HOTPLUG_CPU + prefill_possible_map(); +#endif } /* diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h index 3a544ff..f7a5176 100644 --- a/include/asm-ia64/acpi.h +++ b/include/asm-ia64/acpi.h @@ -106,6 +106,8 @@ extern unsigned int can_cpei_retarget(void); extern unsigned int is_cpu_cpei_target(unsigned int cpu); extern void set_cpei_target_cpu(unsigned int cpu); extern unsigned int get_cpei_target_cpu(void); +extern void prefill_possible_map(void); +extern int additional_cpus; #ifdef CONFIG_ACPI_NUMA /* Proximity bitmap length; _PXM is at most 255 (8 bit)*/ -- cgit v0.10.2 From 61a34937982cace51853b5dc88f86380e31998c0 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Tue, 14 Feb 2006 13:52:54 -0800 Subject: [PATCH] pktcdvd: Don't spam the kernel log when nothing is wrong Change some messages that don't indicate an error so that they are only printed when debugging is enabled. Signed-off-by: Peter Osterlund Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 4e7dbcc..7399976 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -1548,7 +1548,7 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di) case 0x12: /* DVD-RAM */ return 0; default: - printk("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); + VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); return 1; } @@ -1894,7 +1894,7 @@ static int pkt_open_write(struct pktcdvd_device *pd) unsigned int write_speed, media_write_speed, read_speed; if ((ret = pkt_probe_settings(pd))) { - DPRINTK("pktcdvd: %s failed probe\n", pd->name); + VPRINTK("pktcdvd: %s failed probe\n", pd->name); return -EIO; } @@ -2440,7 +2440,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); default: - printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); + VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); return -ENOTTY; } -- cgit v0.10.2 From 01fd9fda2ce462b44bafdac2fe6aacacf23531f2 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Tue, 14 Feb 2006 13:52:55 -0800 Subject: [PATCH] pktcdvd: Allow non-writable media to be mounted If opening for write fails, the open method should return -EROFS. This makes "mount" try again with a read-only mount, instead of just giving up. Signed-off-by: Peter Osterlund Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 7399976..edf6bf2 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -1895,7 +1895,7 @@ static int pkt_open_write(struct pktcdvd_device *pd) if ((ret = pkt_probe_settings(pd))) { VPRINTK("pktcdvd: %s failed probe\n", pd->name); - return -EIO; + return -EROFS; } if ((ret = pkt_set_write_settings(pd))) { @@ -2053,10 +2053,9 @@ static int pkt_open(struct inode *inode, struct file *file) goto out_dec; } } else { - if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { - ret = -EIO; + ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE); + if (ret) goto out_dec; - } /* * needed here as well, since ext2 (among others) may change * the blocksize at mount time -- cgit v0.10.2 From 948423e5ccc33bc257384ad4b339214c577bc926 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Tue, 14 Feb 2006 13:52:56 -0800 Subject: [PATCH] pktcdvd: Don't unlock the door if the disc is in use Unlocking the door when the disc is in use is obviously not good, because then it's possible to eject the disc at the wrong time and cause severe disc data corruption. Signed-off-by: Peter Osterlund Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index edf6bf2..89d8fe0 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2435,7 +2435,8 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u * The door gets locked when the device is opened, so we * have to unlock it or else the eject command fails. */ - pkt_lock_door(pd, 0); + if (pd->refcnt == 1) + pkt_lock_door(pd, 0); return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); default: -- cgit v0.10.2 From 7277232374680595cdbc774fd246b206f56db015 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Tue, 14 Feb 2006 13:52:56 -0800 Subject: [PATCH] pktcdvd: Reduce stack usage Reduce stack usage in the pkt_start_write() function. Even though it's not currently a real problem, the pages and offsets arrays can be eliminated, which saves approximately 1000 bytes of stack space. Signed-off-by: Peter Osterlund Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 89d8fe0..93e44d0 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -645,7 +645,7 @@ static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct pag * b) The data can be used as cache to avoid read requests if we receive a * new write request for the same zone. */ -static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, int *offsets) +static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec) { int f, p, offs; @@ -653,15 +653,15 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in p = 0; offs = 0; for (f = 0; f < pkt->frames; f++) { - if (pages[f] != pkt->pages[p]) { - void *vfrom = kmap_atomic(pages[f], KM_USER0) + offsets[f]; + if (bvec[f].bv_page != pkt->pages[p]) { + void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset; void *vto = page_address(pkt->pages[p]) + offs; memcpy(vto, vfrom, CD_FRAMESIZE); kunmap_atomic(vfrom, KM_USER0); - pages[f] = pkt->pages[p]; - offsets[f] = offs; + bvec[f].bv_page = pkt->pages[p]; + bvec[f].bv_offset = offs; } else { - BUG_ON(offsets[f] != offs); + BUG_ON(bvec[f].bv_offset != offs); } offs += CD_FRAMESIZE; if (offs >= PAGE_SIZE) { @@ -991,18 +991,17 @@ try_next_bio: static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) { struct bio *bio; - struct page *pages[PACKET_MAX_SIZE]; - int offsets[PACKET_MAX_SIZE]; int f; int frames_write; + struct bio_vec *bvec = pkt->w_bio->bi_io_vec; for (f = 0; f < pkt->frames; f++) { - pages[f] = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; - offsets[f] = (f * CD_FRAMESIZE) % PAGE_SIZE; + bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; + bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE; } /* - * Fill-in pages[] and offsets[] with data from orig_bios. + * Fill-in bvec with data from orig_bios. */ frames_write = 0; spin_lock(&pkt->lock); @@ -1024,11 +1023,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) } if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) { - pages[f] = src_bvl->bv_page; - offsets[f] = src_bvl->bv_offset + src_offs; + bvec[f].bv_page = src_bvl->bv_page; + bvec[f].bv_offset = src_bvl->bv_offset + src_offs; } else { pkt_copy_bio_data(bio, segment, src_offs, - pages[f], offsets[f]); + bvec[f].bv_page, bvec[f].bv_offset); } src_offs += CD_FRAMESIZE; frames_write++; @@ -1042,7 +1041,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) BUG_ON(frames_write != pkt->write_size); if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { - pkt_make_local_copy(pkt, pages, offsets); + pkt_make_local_copy(pkt, bvec); pkt->cache_valid = 1; } else { pkt->cache_valid = 0; @@ -1055,17 +1054,9 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) pkt->w_bio->bi_bdev = pd->bdev; pkt->w_bio->bi_end_io = pkt_end_io_packet_write; pkt->w_bio->bi_private = pkt; - for (f = 0; f < pkt->frames; f++) { - if ((f + 1 < pkt->frames) && (pages[f + 1] == pages[f]) && - (offsets[f + 1] = offsets[f] + CD_FRAMESIZE)) { - if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE * 2, offsets[f])) - BUG(); - f++; - } else { - if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE, offsets[f])) - BUG(); - } - } + for (f = 0; f < pkt->frames; f++) + if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset)) + BUG(); VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt); atomic_set(&pkt->io_wait, 1); -- cgit v0.10.2 From 41d78ba55037468e6c86c53e3076d1a74841de39 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 14 Feb 2006 13:52:58 -0800 Subject: [PATCH] compound page: use page[1].lru If a compound page has its own put_page_testzero destructor (the only current example is free_huge_page), that is noted in page[1].mapping of the compound page. But that's rather a poor place to keep it: functions which call set_page_dirty_lock after get_user_pages (e.g. Infiniband's __ib_umem_release) ought to be checking first, otherwise set_page_dirty is liable to crash on what's not the address of a struct address_space. And now I'm about to make that worse: it turns out that every compound page needs a destructor, so we can no longer rely on hugetlb pages going their own special way, to avoid further problems of page->mapping reuse. For example, not many people know that: on 50% of i386 -Os builds, the first tail page of a compound page purports to be PageAnon (when its destructor has an odd address), which surprises page_add_file_rmap. Keep the compound page destructor in page[1].lru.next instead. And to free up the common pairing of mapping and index, also move compound page order from index to lru.prev. Slab reuses page->lru too: but if we ever need slab to use compound pages, it can easily stack its use above this. (akpm: decoded version of the above: the tail pages of a compound page now have ->mapping==NULL, so there's no need for the set_page_dirty[_lock]() caller to check that they're not compund pages before doing the dirty). Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 67f2951..5087077 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -85,7 +85,7 @@ void free_huge_page(struct page *page) BUG_ON(page_count(page)); INIT_LIST_HEAD(&page->lru); - page[1].mapping = NULL; + page[1].lru.next = NULL; /* reset dtor */ spin_lock(&hugetlb_lock); enqueue_huge_page(page); @@ -105,7 +105,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr) } spin_unlock(&hugetlb_lock); set_page_count(page, 1); - page[1].mapping = (void *)free_huge_page; + page[1].lru.next = (void *)free_huge_page; /* set dtor */ for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) clear_user_highpage(&page[i], addr); return page; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index dde04ff..eec89ab 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -169,20 +169,17 @@ static void bad_page(struct page *page) * All pages have PG_compound set. All pages have their ->private pointing at * the head page (even the head page has this). * - * The first tail page's ->mapping, if non-zero, holds the address of the - * compound page's put_page() function. - * - * The order of the allocation is stored in the first tail page's ->index - * This is only for debug at present. This usage means that zero-order pages - * may not be compound. + * The first tail page's ->lru.next holds the address of the compound page's + * put_page() function. Its ->lru.prev holds the order of allocation. + * This usage means that zero-order pages may not be compound. */ static void prep_compound_page(struct page *page, unsigned long order) { int i; int nr_pages = 1 << order; - page[1].mapping = NULL; - page[1].index = order; + page[1].lru.next = NULL; /* set dtor */ + page[1].lru.prev = (void *)order; for (i = 0; i < nr_pages; i++) { struct page *p = page + i; @@ -196,7 +193,7 @@ static void destroy_compound_page(struct page *page, unsigned long order) int i; int nr_pages = 1 << order; - if (unlikely(page[1].index != order)) + if (unlikely((unsigned long)page[1].lru.prev != order)) bad_page(page); for (i = 0; i < nr_pages; i++) { diff --git a/mm/swap.c b/mm/swap.c index 7624742..cce3dda 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -40,7 +40,7 @@ static void put_compound_page(struct page *page) if (put_page_testzero(page)) { void (*dtor)(struct page *page); - dtor = (void (*)(struct page *))page[1].mapping; + dtor = (void (*)(struct page *))page[1].lru.next; (*dtor)(page); } } -- cgit v0.10.2 From d98c7a09843621f1b145ca5ae8ed03ff04085edb Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 14 Feb 2006 13:52:59 -0800 Subject: [PATCH] compound page: default destructor Somehow I imagined that calling a NULL destructor would free a compound page rather than oopsing. No, we must supply a default destructor, __free_pages_ok using the order noted by prep_compound_page. hugetlb can still replace this as before with its own free_huge_page pointer. The case that needs this is not common: rarely does put_compound_page's put_page_testzero bring the count down to 0. But if get_user_pages is applied to some part of a compound page, without immediate release (e.g. AIO or Infiniband), then it's possible for its put_page to come after the containing vma has been unmapped and the driver done its free_pages. That's just the kind of case compound pages are supposed to be guarding against (but Nick points out, nor did PageReserved handle this right). Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/page_alloc.c b/mm/page_alloc.c index eec89ab..62c1225 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -56,6 +56,7 @@ long nr_swap_pages; int percpu_pagelist_fraction; static void fastcall free_hot_cold_page(struct page *page, int cold); +static void __free_pages_ok(struct page *page, unsigned int order); /* * results with 256, 32 in the lowmem_reserve sysctl: @@ -173,12 +174,18 @@ static void bad_page(struct page *page) * put_page() function. Its ->lru.prev holds the order of allocation. * This usage means that zero-order pages may not be compound. */ + +static void free_compound_page(struct page *page) +{ + __free_pages_ok(page, (unsigned long)page[1].lru.prev); +} + static void prep_compound_page(struct page *page, unsigned long order) { int i; int nr_pages = 1 << order; - page[1].lru.next = NULL; /* set dtor */ + page[1].lru.next = (void *)free_compound_page; /* set dtor */ page[1].lru.prev = (void *)order; for (i = 0; i < nr_pages; i++) { struct page *p = page + i; -- cgit v0.10.2 From 16bf134840da3920ded1290973c56ec214636f12 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 14 Feb 2006 13:52:59 -0800 Subject: [PATCH] compound page: no access_process_vm check The PageCompound check before access_process_vm's set_page_dirty_lock is no longer necessary, so remove it. But leave the PageCompound checks in bio_set_pages_dirty, dio_bio_complete and nfs_free_user_pages: at least some of those were introduced as a little optimization on hugetlb pages. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 5f33cdb..d2cf144 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -242,8 +242,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in if (write) { copy_to_user_page(vma, page, addr, maddr + offset, buf, bytes); - if (!PageCompound(page)) - set_page_dirty_lock(page); + set_page_dirty_lock(page); } else { copy_from_user_page(vma, page, addr, buf, maddr + offset, bytes); -- cgit v0.10.2 From da965822abd18a17d7cffe1d511f48951c82dfb6 Mon Sep 17 00:00:00 2001 From: Paul Fulghum Date: Tue, 14 Feb 2006 13:53:00 -0800 Subject: [PATCH] tty reference count fix Fix hole where tty structure can be released when reference count is non zero. Existing code can sleep without tty_sem protection between deciding to release the tty structure (setting local variables tty_closing and otty_closing) and setting TTY_CLOSING to prevent further opens. An open can occur during this interval causing release_dev() to free the tty structure while it is still referenced. This should fix bugzilla.kernel.org [Bug 6041] New: Unable to handle kernel paging request In Bug 6041, tty_open() oopes on accessing the tty structure it has successfully claimed. Bug was on SMP machine with the same tty being opened and closed by multiple processes, and DEBUG_PAGEALLOC enabled. Signed-off-by: Paul Fulghum Cc: Alan Cox Cc: Jesper Juhl Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index a23816d..e9bba94 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1841,7 +1841,6 @@ static void release_dev(struct file * filp) tty_closing = tty->count <= 1; o_tty_closing = o_tty && (o_tty->count <= (pty_master ? 1 : 0)); - up(&tty_sem); do_sleep = 0; if (tty_closing) { @@ -1869,6 +1868,7 @@ static void release_dev(struct file * filp) printk(KERN_WARNING "release_dev: %s: read/write wait queue " "active!\n", tty_name(tty, buf)); + up(&tty_sem); schedule(); } @@ -1877,8 +1877,6 @@ static void release_dev(struct file * filp) * both sides, and we've completed the last operation that could * block, so it's safe to proceed with closing. */ - - down(&tty_sem); if (pty_master) { if (--o_tty->count < 0) { printk(KERN_WARNING "release_dev: bad pty slave count " @@ -1892,7 +1890,6 @@ static void release_dev(struct file * filp) tty->count, tty_name(tty, buf)); tty->count = 0; } - up(&tty_sem); /* * We've decremented tty->count, so we need to remove this file @@ -1937,6 +1934,8 @@ static void release_dev(struct file * filp) read_unlock(&tasklist_lock); } + up(&tty_sem); + /* check whether both sides are closing ... */ if (!tty_closing || (o_tty && !o_tty_closing)) return; -- cgit v0.10.2 From be5efffb762fa4a7b9a7a45ebf34b13e3bf5a2d8 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 14 Feb 2006 13:53:02 -0800 Subject: [PATCH] HPET: handle multiple ACPI EXTENDED_IRQ resources When the _CRS for a single HPET contains multiple EXTENDED_IRQ resources, we overwrote hdp->hd_nirqs every time we found one. So the driver worked when all the IRQs were described in a single EXTENDED_IRQ resource, but failed when multiple resources were used. (Strictly speaking, I think the latter is actually more correct, but both styles have been used.) Someday we should remove all the ACPI stuff from hpet.c and use PNP driver registration instead. But currently PNP_MAX_IRQ is 2, and HPETs often have more IRQs. Hint, hint, Adam :-) Signed-off-by: Bjorn Helgaas Acked-by: Bob Picco Cc: Venkatesh Pallipadi Cc: Len Brown Cc: Adam Belay Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 66a2fee..ef140eb 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -956,22 +956,18 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) } } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { struct acpi_resource_extended_irq *irqp; - int i; + int i, irq; irqp = &res->data.extended_irq; - if (irqp->interrupt_count > 0) { - hdp->hd_nirqs = irqp->interrupt_count; - - for (i = 0; i < hdp->hd_nirqs; i++) { - int rc = - acpi_register_gsi(irqp->interrupts[i], - irqp->triggering, - irqp->polarity); - if (rc < 0) - return AE_ERROR; - hdp->hd_irq[i] = rc; - } + for (i = 0; i < irqp->interrupt_count; i++) { + irq = acpi_register_gsi(irqp->interrupts[i], + irqp->triggering, irqp->polarity); + if (irq < 0) + return AE_ERROR; + + hdp->hd_irq[hdp->hd_nirqs] = irq; + hdp->hd_nirqs++; } } -- cgit v0.10.2 From 7c8903f6373f9abecf060bad53ca36bc4ac037f2 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Tue, 14 Feb 2006 13:53:03 -0800 Subject: [PATCH] jbd: revert checkpoint list changes This patch reverts commit f93ea411b73594f7d144855fd34278bcf34a9afc: [PATCH] jbd: split checkpoint lists This broke journal_flush() for OCFS2, which is its method of being sure that metadata is sent to disk for another node. And two related commits 8d3c7fce2d20ecc3264c8d8c91ae3beacdeaed1b and 43c3e6f5abdf6acac9b90c86bf03f995bf7d3d92 with the subjects: [PATCH] jbd: log_do_checkpoint fix [PATCH] jbd: remove_transaction fix These seem to be incremental bugfixes on the original patch and as such are no longer needed. Signed-off-by: Mark Fasheh Cc: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index e6265a0..543ed54 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c @@ -24,75 +24,29 @@ #include /* - * Unlink a buffer from a transaction checkpoint list. + * Unlink a buffer from a transaction. * * Called with j_list_lock held. */ -static void __buffer_unlink_first(struct journal_head *jh) +static inline void __buffer_unlink(struct journal_head *jh) { transaction_t *transaction; transaction = jh->b_cp_transaction; + jh->b_cp_transaction = NULL; jh->b_cpnext->b_cpprev = jh->b_cpprev; jh->b_cpprev->b_cpnext = jh->b_cpnext; - if (transaction->t_checkpoint_list == jh) { + if (transaction->t_checkpoint_list == jh) transaction->t_checkpoint_list = jh->b_cpnext; - if (transaction->t_checkpoint_list == jh) - transaction->t_checkpoint_list = NULL; - } -} - -/* - * Unlink a buffer from a transaction checkpoint(io) list. - * - * Called with j_list_lock held. - */ - -static inline void __buffer_unlink(struct journal_head *jh) -{ - transaction_t *transaction; - - transaction = jh->b_cp_transaction; - - __buffer_unlink_first(jh); - if (transaction->t_checkpoint_io_list == jh) { - transaction->t_checkpoint_io_list = jh->b_cpnext; - if (transaction->t_checkpoint_io_list == jh) - transaction->t_checkpoint_io_list = NULL; - } -} - -/* - * Move a buffer from the checkpoint list to the checkpoint io list - * - * Called with j_list_lock held - */ - -static inline void __buffer_relink_io(struct journal_head *jh) -{ - transaction_t *transaction; - - transaction = jh->b_cp_transaction; - __buffer_unlink_first(jh); - - if (!transaction->t_checkpoint_io_list) { - jh->b_cpnext = jh->b_cpprev = jh; - } else { - jh->b_cpnext = transaction->t_checkpoint_io_list; - jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev; - jh->b_cpprev->b_cpnext = jh; - jh->b_cpnext->b_cpprev = jh; - } - transaction->t_checkpoint_io_list = jh; + if (transaction->t_checkpoint_list == jh) + transaction->t_checkpoint_list = NULL; } /* * Try to release a checkpointed buffer from its transaction. - * Returns 1 if we released it and 2 if we also released the - * whole transaction. - * + * Returns 1 if we released it. * Requires j_list_lock * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it */ @@ -103,11 +57,12 @@ static int __try_to_free_cp_buf(struct journal_head *jh) if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) { JBUFFER_TRACE(jh, "remove from checkpoint list"); - ret = __journal_remove_checkpoint(jh) + 1; + __journal_remove_checkpoint(jh); jbd_unlock_bh_state(bh); journal_remove_journal_head(bh); BUFFER_TRACE(bh, "release"); __brelse(bh); + ret = 1; } else { jbd_unlock_bh_state(bh); } @@ -162,53 +117,83 @@ static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh) } /* - * Clean up transaction's list of buffers submitted for io. - * We wait for any pending IO to complete and remove any clean - * buffers. Note that we take the buffers in the opposite ordering - * from the one in which they were submitted for IO. + * Clean up a transaction's checkpoint list. + * + * We wait for any pending IO to complete and make sure any clean + * buffers are removed from the transaction. + * + * Return 1 if we performed any actions which might have destroyed the + * checkpoint. (journal_remove_checkpoint() deletes the transaction when + * the last checkpoint buffer is cleansed) * * Called with j_list_lock held. */ - -static void __wait_cp_io(journal_t *journal, transaction_t *transaction) +static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) { - struct journal_head *jh; + struct journal_head *jh, *next_jh, *last_jh; struct buffer_head *bh; - tid_t this_tid; - int released = 0; - - this_tid = transaction->t_tid; -restart: - /* Didn't somebody clean up the transaction in the meanwhile */ - if (journal->j_checkpoint_transactions != transaction || - transaction->t_tid != this_tid) - return; - while (!released && transaction->t_checkpoint_io_list) { - jh = transaction->t_checkpoint_io_list; + int ret = 0; + + assert_spin_locked(&journal->j_list_lock); + jh = transaction->t_checkpoint_list; + if (!jh) + return 0; + + last_jh = jh->b_cpprev; + next_jh = jh; + do { + jh = next_jh; bh = jh2bh(jh); - if (!jbd_trylock_bh_state(bh)) { - jbd_sync_bh(journal, bh); - spin_lock(&journal->j_list_lock); - goto restart; - } if (buffer_locked(bh)) { atomic_inc(&bh->b_count); spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); wait_on_buffer(bh); /* the journal_head may have gone by now */ BUFFER_TRACE(bh, "brelse"); __brelse(bh); - spin_lock(&journal->j_list_lock); - goto restart; + goto out_return_1; } + /* - * Now in whatever state the buffer currently is, we know that - * it has been written out and so we can drop it from the list + * This is foul */ - released = __journal_remove_checkpoint(jh); - jbd_unlock_bh_state(bh); - } + if (!jbd_trylock_bh_state(bh)) { + jbd_sync_bh(journal, bh); + goto out_return_1; + } + + if (jh->b_transaction != NULL) { + transaction_t *t = jh->b_transaction; + tid_t tid = t->t_tid; + + spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + log_start_commit(journal, tid); + log_wait_commit(journal, tid); + goto out_return_1; + } + + /* + * AKPM: I think the buffer_jbddirty test is redundant - it + * shouldn't have NULL b_transaction? + */ + next_jh = jh->b_cpnext; + if (!buffer_dirty(bh) && !buffer_jbddirty(bh)) { + BUFFER_TRACE(bh, "remove from checkpoint"); + __journal_remove_checkpoint(jh); + jbd_unlock_bh_state(bh); + journal_remove_journal_head(bh); + __brelse(bh); + ret = 1; + } else { + jbd_unlock_bh_state(bh); + } + } while (jh != last_jh); + + return ret; +out_return_1: + spin_lock(&journal->j_list_lock); + return 1; } #define NR_BATCH 64 @@ -218,7 +203,9 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count) { int i; + spin_unlock(&journal->j_list_lock); ll_rw_block(SWRITE, *batch_count, bhs); + spin_lock(&journal->j_list_lock); for (i = 0; i < *batch_count; i++) { struct buffer_head *bh = bhs[i]; clear_buffer_jwrite(bh); @@ -234,46 +221,19 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count) * Return 1 if something happened which requires us to abort the current * scan of the checkpoint list. * - * Called with j_list_lock held and drops it if 1 is returned + * Called with j_list_lock held. * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it */ -static int __process_buffer(journal_t *journal, struct journal_head *jh, - struct buffer_head **bhs, int *batch_count) +static int __flush_buffer(journal_t *journal, struct journal_head *jh, + struct buffer_head **bhs, int *batch_count, + int *drop_count) { struct buffer_head *bh = jh2bh(jh); int ret = 0; - if (buffer_locked(bh)) { - get_bh(bh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - wait_on_buffer(bh); - /* the journal_head may have gone by now */ - BUFFER_TRACE(bh, "brelse"); - put_bh(bh); - ret = 1; - } - else if (jh->b_transaction != NULL) { - transaction_t *t = jh->b_transaction; - tid_t tid = t->t_tid; + if (buffer_dirty(bh) && !buffer_locked(bh) && jh->b_jlist == BJ_None) { + J_ASSERT_JH(jh, jh->b_transaction == NULL); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - log_start_commit(journal, tid); - log_wait_commit(journal, tid); - ret = 1; - } - else if (!buffer_dirty(bh)) { - J_ASSERT_JH(jh, !buffer_jbddirty(bh)); - BUFFER_TRACE(bh, "remove from checkpoint"); - __journal_remove_checkpoint(jh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - journal_remove_journal_head(bh); - put_bh(bh); - ret = 1; - } - else { /* * Important: we are about to write the buffer, and * possibly block, while still holding the journal lock. @@ -286,30 +246,45 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh, J_ASSERT_BH(bh, !buffer_jwrite(bh)); set_buffer_jwrite(bh); bhs[*batch_count] = bh; - __buffer_relink_io(jh); jbd_unlock_bh_state(bh); (*batch_count)++; if (*batch_count == NR_BATCH) { - spin_unlock(&journal->j_list_lock); __flush_batch(journal, bhs, batch_count); ret = 1; } + } else { + int last_buffer = 0; + if (jh->b_cpnext == jh) { + /* We may be about to drop the transaction. Tell the + * caller that the lists have changed. + */ + last_buffer = 1; + } + if (__try_to_free_cp_buf(jh)) { + (*drop_count)++; + ret = last_buffer; + } } return ret; } /* - * Perform an actual checkpoint. We take the first transaction on the - * list of transactions to be checkpointed and send all its buffers - * to disk. We submit larger chunks of data at once. + * Perform an actual checkpoint. We don't write out only enough to + * satisfy the current blocked requests: rather we submit a reasonably + * sized chunk of the outstanding data to disk at once for + * efficiency. __log_wait_for_space() will retry if we didn't free enough. * + * However, we _do_ take into account the amount requested so that once + * the IO has been queued, we can return as soon as enough of it has + * completed to disk. + * * The journal should be locked before calling this function. */ int log_do_checkpoint(journal_t *journal) { - transaction_t *transaction; - tid_t this_tid; int result; + int batch_count = 0; + struct buffer_head *bhs[NR_BATCH]; jbd_debug(1, "Start checkpoint\n"); @@ -324,70 +299,79 @@ int log_do_checkpoint(journal_t *journal) return result; /* - * OK, we need to start writing disk blocks. Take one transaction - * and write it. + * OK, we need to start writing disk blocks. Try to free up a + * quarter of the log in a single checkpoint if we can. */ - spin_lock(&journal->j_list_lock); - if (!journal->j_checkpoint_transactions) - goto out; - transaction = journal->j_checkpoint_transactions; - this_tid = transaction->t_tid; -restart: /* - * If someone cleaned up this transaction while we slept, we're - * done (maybe it's a new transaction, but it fell at the same - * address). + * AKPM: check this code. I had a feeling a while back that it + * degenerates into a busy loop at unmount time. */ - if (journal->j_checkpoint_transactions == transaction && - transaction->t_tid == this_tid) { - int batch_count = 0; - struct buffer_head *bhs[NR_BATCH]; - struct journal_head *jh; - int retry = 0; - - while (!retry && transaction->t_checkpoint_list) { + spin_lock(&journal->j_list_lock); + while (journal->j_checkpoint_transactions) { + transaction_t *transaction; + struct journal_head *jh, *last_jh, *next_jh; + int drop_count = 0; + int cleanup_ret, retry = 0; + tid_t this_tid; + + transaction = journal->j_checkpoint_transactions; + this_tid = transaction->t_tid; + jh = transaction->t_checkpoint_list; + last_jh = jh->b_cpprev; + next_jh = jh; + do { struct buffer_head *bh; - jh = transaction->t_checkpoint_list; + jh = next_jh; + next_jh = jh->b_cpnext; bh = jh2bh(jh); if (!jbd_trylock_bh_state(bh)) { jbd_sync_bh(journal, bh); + spin_lock(&journal->j_list_lock); retry = 1; break; } - retry = __process_buffer(journal, jh, bhs, - &batch_count); - if (!retry && - lock_need_resched(&journal->j_list_lock)) { - spin_unlock(&journal->j_list_lock); + retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count); + if (cond_resched_lock(&journal->j_list_lock)) { retry = 1; break; } - } + } while (jh != last_jh && !retry); if (batch_count) { - if (!retry) { - spin_unlock(&journal->j_list_lock); - retry = 1; - } __flush_batch(journal, bhs, &batch_count); + retry = 1; } - if (retry) { - spin_lock(&journal->j_list_lock); - goto restart; - } /* - * Now we have cleaned up the first transaction's checkpoint - * list. Let's clean up the second one. + * If someone cleaned up this transaction while we slept, we're + * done + */ + if (journal->j_checkpoint_transactions != transaction) + break; + if (retry) + continue; + /* + * Maybe it's a new transaction, but it fell at the same + * address */ - __wait_cp_io(journal, transaction); + if (transaction->t_tid != this_tid) + continue; + /* + * We have walked the whole transaction list without + * finding anything to write to disk. We had better be + * able to make some progress or we are in trouble. + */ + cleanup_ret = __cleanup_transaction(journal, transaction); + J_ASSERT(drop_count != 0 || cleanup_ret != 0); + if (journal->j_checkpoint_transactions != transaction) + break; } -out: spin_unlock(&journal->j_list_lock); result = cleanup_journal_tail(journal); if (result < 0) return result; + return 0; } @@ -472,91 +456,52 @@ int cleanup_journal_tail(journal_t *journal) /* Checkpoint list management */ /* - * journal_clean_one_cp_list - * - * Find all the written-back checkpoint buffers in the given list and release them. - * - * Called with the journal locked. - * Called with j_list_lock held. - * Returns number of bufers reaped (for debug) - */ - -static int journal_clean_one_cp_list(struct journal_head *jh, int *released) -{ - struct journal_head *last_jh; - struct journal_head *next_jh = jh; - int ret, freed = 0; - - *released = 0; - if (!jh) - return 0; - - last_jh = jh->b_cpprev; - do { - jh = next_jh; - next_jh = jh->b_cpnext; - /* Use trylock because of the ranking */ - if (jbd_trylock_bh_state(jh2bh(jh))) { - ret = __try_to_free_cp_buf(jh); - if (ret) { - freed++; - if (ret == 2) { - *released = 1; - return freed; - } - } - } - /* - * This function only frees up some memory if possible so we - * dont have an obligation to finish processing. Bail out if - * preemption requested: - */ - if (need_resched()) - return freed; - } while (jh != last_jh); - - return freed; -} - -/* * journal_clean_checkpoint_list * * Find all the written-back checkpoint buffers in the journal and release them. * * Called with the journal locked. * Called with j_list_lock held. - * Returns number of buffers reaped (for debug) + * Returns number of bufers reaped (for debug) */ int __journal_clean_checkpoint_list(journal_t *journal) { transaction_t *transaction, *last_transaction, *next_transaction; - int ret = 0, released; + int ret = 0; transaction = journal->j_checkpoint_transactions; - if (!transaction) + if (transaction == 0) goto out; last_transaction = transaction->t_cpprev; next_transaction = transaction; do { + struct journal_head *jh; + transaction = next_transaction; next_transaction = transaction->t_cpnext; - ret += journal_clean_one_cp_list(transaction-> - t_checkpoint_list, &released); - if (need_resched()) - goto out; - if (released) - continue; - /* - * It is essential that we are as careful as in the case of - * t_checkpoint_list with removing the buffer from the list as - * we can possibly see not yet submitted buffers on io_list - */ - ret += journal_clean_one_cp_list(transaction-> - t_checkpoint_io_list, &released); - if (need_resched()) - goto out; + jh = transaction->t_checkpoint_list; + if (jh) { + struct journal_head *last_jh = jh->b_cpprev; + struct journal_head *next_jh = jh; + + do { + jh = next_jh; + next_jh = jh->b_cpnext; + /* Use trylock because of the ranknig */ + if (jbd_trylock_bh_state(jh2bh(jh))) + ret += __try_to_free_cp_buf(jh); + /* + * This function only frees up some memory + * if possible so we dont have an obligation + * to finish processing. Bail out if preemption + * requested: + */ + if (need_resched()) + goto out; + } while (jh != last_jh); + } } while (transaction != last_transaction); out: return ret; @@ -571,22 +516,18 @@ out: * buffer updates committed in that transaction have safely been stored * elsewhere on disk. To achieve this, all of the buffers in a * transaction need to be maintained on the transaction's checkpoint - * lists until they have been rewritten, at which point this function is + * list until they have been rewritten, at which point this function is * called to remove the buffer from the existing transaction's - * checkpoint lists. - * - * The function returns 1 if it frees the transaction, 0 otherwise. + * checkpoint list. * * This function is called with the journal locked. * This function is called with j_list_lock held. - * This function is called with jbd_lock_bh_state(jh2bh(jh)) */ -int __journal_remove_checkpoint(struct journal_head *jh) +void __journal_remove_checkpoint(struct journal_head *jh) { transaction_t *transaction; journal_t *journal; - int ret = 0; JBUFFER_TRACE(jh, "entry"); @@ -597,10 +538,8 @@ int __journal_remove_checkpoint(struct journal_head *jh) journal = transaction->t_journal; __buffer_unlink(jh); - jh->b_cp_transaction = NULL; - if (transaction->t_checkpoint_list != NULL || - transaction->t_checkpoint_io_list != NULL) + if (transaction->t_checkpoint_list != NULL) goto out; JBUFFER_TRACE(jh, "transaction has no more buffers"); @@ -626,10 +565,8 @@ int __journal_remove_checkpoint(struct journal_head *jh) /* Just in case anybody was waiting for more transactions to be checkpointed... */ wake_up(&journal->j_wait_logspace); - ret = 1; out: JBUFFER_TRACE(jh, "exit"); - return ret; } /* @@ -691,7 +628,6 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction) J_ASSERT(transaction->t_shadow_list == NULL); J_ASSERT(transaction->t_log_list == NULL); J_ASSERT(transaction->t_checkpoint_list == NULL); - J_ASSERT(transaction->t_checkpoint_io_list == NULL); J_ASSERT(transaction->t_updates == 0); J_ASSERT(journal->j_committing_transaction != transaction); J_ASSERT(journal->j_running_transaction != transaction); diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 29e62d9..002ad2b 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c @@ -829,8 +829,7 @@ restart_loop: journal->j_committing_transaction = NULL; spin_unlock(&journal->j_state_lock); - if (commit_transaction->t_checkpoint_list == NULL && - commit_transaction->t_checkpoint_io_list == NULL) { + if (commit_transaction->t_checkpoint_list == NULL) { __journal_drop_transaction(journal, commit_transaction); } else { if (journal->j_checkpoint_transactions == NULL) { diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 0fe4aa8..41ee799 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -498,12 +498,6 @@ struct transaction_s struct journal_head *t_checkpoint_list; /* - * Doubly-linked circular list of all buffers submitted for IO while - * checkpointing. [j_list_lock] - */ - struct journal_head *t_checkpoint_io_list; - - /* * Doubly-linked circular list of temporary buffers currently undergoing * IO in the log [j_list_lock] */ @@ -852,7 +846,7 @@ extern void journal_commit_transaction(journal_t *); /* Checkpoint list management */ int __journal_clean_checkpoint_list(journal_t *journal); -int __journal_remove_checkpoint(struct journal_head *); +void __journal_remove_checkpoint(struct journal_head *); void __journal_insert_checkpoint(struct journal_head *, transaction_t *); /* Buffer IO */ -- cgit v0.10.2 From 5ac5f9d1ce8492163dbde5d357dc5d03becf7e36 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 14 Feb 2006 13:53:04 -0800 Subject: [PATCH] NLM: Fix the NLM_GRANTED callback checks If 2 threads attached to the same process are blocking on different locks on different files (maybe even on different servers) but have the same lock arguments (i.e. same offset+length - actually quite common, since most processes try to lock the entire file) then the first GRANTED call that wakes one up will also wake the other. Currently when the NLM_GRANTED callback comes in, lockd walks the list of blocked locks in search of a match to the lock that the NLM server has granted. Although it checks the lock pid, start and end, it fails to check the filehandle and the server address. By checking the filehandle and server IP address, we ensure that this only happens if the locks truly are referencing the same file. Signed-off-by: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 3eaf6e7..da6354b 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -111,9 +111,10 @@ long nlmclnt_block(struct nlm_rqst *req, long timeout) /* * The server lockd has called us back to tell us the lock was granted */ -u32 -nlmclnt_grant(struct nlm_lock *lock) +u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock) { + const struct file_lock *fl = &lock->fl; + const struct nfs_fh *fh = &lock->fh; struct nlm_wait *block; u32 res = nlm_lck_denied; @@ -122,14 +123,20 @@ nlmclnt_grant(struct nlm_lock *lock) * Warning: must not use cookie to match it! */ list_for_each_entry(block, &nlm_blocked, b_list) { - if (nlm_compare_locks(block->b_lock, &lock->fl)) { - /* Alright, we found a lock. Set the return status - * and wake up the caller - */ - block->b_status = NLM_LCK_GRANTED; - wake_up(&block->b_wait); - res = nlm_granted; - } + struct file_lock *fl_blocked = block->b_lock; + + if (!nlm_compare_locks(fl_blocked, fl)) + continue; + if (!nlm_cmp_addr(&block->b_host->h_addr, addr)) + continue; + if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_dentry->d_inode) ,fh) != 0) + continue; + /* Alright, we found a lock. Set the return status + * and wake up the caller + */ + block->b_status = NLM_LCK_GRANTED; + wake_up(&block->b_wait); + res = nlm_granted; } return res; } diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 4063095..b10f913 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -228,7 +228,7 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, resp->cookie = argp->cookie; dprintk("lockd: GRANTED called\n"); - resp->status = nlmclnt_grant(&argp->lock); + resp->status = nlmclnt_grant(&rqstp->rq_addr, &argp->lock); dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); return rpc_success; } diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 3bc437e..35681d9 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -256,7 +256,7 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, resp->cookie = argp->cookie; dprintk("lockd: GRANTED called\n"); - resp->status = nlmclnt_grant(&argp->lock); + resp->status = nlmclnt_grant(&rqstp->rq_addr, &argp->lock); dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); return rpc_success; } diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 920766c..ef21ed2 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -149,7 +149,7 @@ struct nlm_rqst * nlmclnt_alloc_call(void); int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl); void nlmclnt_finish_block(struct nlm_rqst *req); long nlmclnt_block(struct nlm_rqst *req, long timeout); -u32 nlmclnt_grant(struct nlm_lock *); +u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); void nlmclnt_recovery(struct nlm_host *, u32); int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); int nlmclnt_setgrantargs(struct nlm_rqst *, struct nlm_lock *); @@ -204,7 +204,7 @@ nlmsvc_file_inode(struct nlm_file *file) * Compare two host addresses (needs modifying for ipv6) */ static __inline__ int -nlm_cmp_addr(struct sockaddr_in *sin1, struct sockaddr_in *sin2) +nlm_cmp_addr(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2) { return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr; } @@ -214,7 +214,7 @@ nlm_cmp_addr(struct sockaddr_in *sin1, struct sockaddr_in *sin2) * When the second lock is of type F_UNLCK, this acts like a wildcard. */ static __inline__ int -nlm_compare_locks(struct file_lock *fl1, struct file_lock *fl2) +nlm_compare_locks(const struct file_lock *fl1, const struct file_lock *fl2) { return fl1->fl_pid == fl2->fl_pid && fl1->fl_start == fl2->fl_start -- cgit v0.10.2 From 8b09fb34513225d87d511c7e8f29c0fd3cf860e0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 14 Feb 2006 13:53:05 -0800 Subject: [PATCH] fix x86 topology export in sysfs for subarchitectures The correct way to export hyperthreading based functions is to predicate them on CONFIG_X86_HT. Without this, the topology exporting patch breaks the build on all non-PC x86 subarchitectures. Signed-off-by: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h index af503a1..aa958c6 100644 --- a/include/asm-i386/topology.h +++ b/include/asm-i386/topology.h @@ -27,7 +27,7 @@ #ifndef _ASM_I386_TOPOLOGY_H #define _ASM_I386_TOPOLOGY_H -#ifdef CONFIG_SMP +#ifdef CONFIG_X86_HT #define topology_physical_package_id(cpu) \ (phys_proc_id[cpu] == BAD_APICID ? -1 : phys_proc_id[cpu]) #define topology_core_id(cpu) \ -- cgit v0.10.2 From 61b9a26ae6d308ade964db122e0e89299586422c Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Tue, 14 Feb 2006 13:53:06 -0800 Subject: [PATCH] Fix NULL pointer dereference in isdn_tty_at_cout The changes in the tty related code introduced wrong parenthesis in a if condition in the isdn_tty_at_cout function. This caused access to index -1 in the dev->drv[] array. This patch change it back to the correct condition from the previous versions. Signed-off-by: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index f190a99..3936336 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -2359,8 +2359,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) /* use queue instead of direct, if online and */ /* data is in queue or buffer is full */ - if ((info->online && tty_buffer_request_room(tty, l) < l) || - (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { + if (info->online && ((tty_buffer_request_room(tty, l) < l) || + !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { skb = alloc_skb(l, GFP_ATOMIC); if (!skb) { spin_unlock_irqrestore(&info->readlock, flags); -- cgit v0.10.2 From 8861da31e3b3e3df7b05e7b157230de3d486e53b Mon Sep 17 00:00:00 2001 From: Jim Keniston Date: Tue, 14 Feb 2006 13:53:06 -0800 Subject: [PATCH] kprobes: Update Documentation/kprobes.txt Update Documentation/kprobes.txt to reflect Kprobes enhancements and other recent developments. Acked-by: Ananth Mavinakayanahalli Signed-off-by: Jim Keniston Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 0ea5a0c..2c3b1ea 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt @@ -136,17 +136,20 @@ Kprobes, jprobes, and return probes are implemented on the following architectures: - i386 -- x86_64 (AMD-64, E64MT) +- x86_64 (AMD-64, EM64T) - ppc64 -- ia64 (Support for probes on certain instruction types is still in progress.) +- ia64 (Does not support probes on instruction slot1.) - sparc64 (Return probes not yet implemented.) 3. Configuring Kprobes When configuring the kernel using make menuconfig/xconfig/oldconfig, -ensure that CONFIG_KPROBES is set to "y". Under "Kernel hacking", -look for "Kprobes". You may have to enable "Kernel debugging" -(CONFIG_DEBUG_KERNEL) before you can enable Kprobes. +ensure that CONFIG_KPROBES is set to "y". Under "Instrumentation +Support", look for "Kprobes". + +So that you can load and unload Kprobes-based instrumentation modules, +make sure "Loadable module support" (CONFIG_MODULES) and "Module +unloading" (CONFIG_MODULE_UNLOAD) are set to "y". You may also want to ensure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name() @@ -262,18 +265,18 @@ at any time after the probe has been registered. 5. Kprobes Features and Limitations -As of Linux v2.6.12, Kprobes allows multiple probes at the same -address. Currently, however, there cannot be multiple jprobes on -the same function at the same time. +Kprobes allows multiple probes at the same address. Currently, +however, there cannot be multiple jprobes on the same function at +the same time. In general, you can install a probe anywhere in the kernel. In particular, you can probe interrupt handlers. Known exceptions are discussed in this section. -For obvious reasons, it's a bad idea to install a probe in -the code that implements Kprobes (mostly kernel/kprobes.c and -arch/*/kernel/kprobes.c). A patch in the v2.6.13 timeframe instructs -Kprobes to reject such requests. +The register_*probe functions will return -EINVAL if you attempt +to install a probe in the code that implements Kprobes (mostly +kernel/kprobes.c and arch/*/kernel/kprobes.c, but also functions such +as do_page_fault and notifier_call_chain). If you install a probe in an inline-able function, Kprobes makes no attempt to chase down all inline instances of the function and @@ -290,18 +293,14 @@ from the accidental ones. Don't drink and probe. Kprobes makes no attempt to prevent probe handlers from stepping on each other -- e.g., probing printk() and then calling printk() from a -probe handler. As of Linux v2.6.12, if a probe handler hits a probe, -that second probe's handlers won't be run in that instance. - -In Linux v2.6.12 and previous versions, Kprobes' data structures are -protected by a single lock that is held during probe registration and -unregistration and while handlers are run. Thus, no two handlers -can run simultaneously. To improve scalability on SMP systems, -this restriction will probably be removed soon, in which case -multiple handlers (or multiple instances of the same handler) may -run concurrently on different CPUs. Code your handlers accordingly. - -Kprobes does not use semaphores or allocate memory except during +probe handler. If a probe handler hits a probe, that second probe's +handlers won't be run in that instance, and the kprobe.nmissed member +of the second probe will be incremented. + +As of Linux v2.6.15-rc1, multiple handlers (or multiple instances of +the same handler) may run concurrently on different CPUs. + +Kprobes does not use mutexes or allocate memory except during registration and unregistration. Probe handlers are run with preemption disabled. Depending on the @@ -316,11 +315,18 @@ address instead of the real return address for kretprobed functions. (As far as we can tell, __builtin_return_address() is used only for instrumentation and error reporting.) -If the number of times a function is called does not match the -number of times it returns, registering a return probe on that -function may produce undesirable results. We have the do_exit() -and do_execve() cases covered. do_fork() is not an issue. We're -unaware of other specific cases where this could be a problem. +If the number of times a function is called does not match the number +of times it returns, registering a return probe on that function may +produce undesirable results. We have the do_exit() case covered. +do_execve() and do_fork() are not an issue. We're unaware of other +specific cases where this could be a problem. + +If, upon entry to or exit from a function, the CPU is running on +a stack other than that of the current task, registering a return +probe on that function may produce undesirable results. For this +reason, Kprobes doesn't support return probes (or kprobes or jprobes) +on the x86_64 version of __switch_to(); the registration functions +return -EINVAL. 6. Probe Overhead @@ -347,14 +353,12 @@ k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99 7. TODO -a. SystemTap (http://sourceware.org/systemtap): Work in progress -to provide a simplified programming interface for probe-based -instrumentation. -b. Improved SMP scalability: Currently, work is in progress to handle -multiple kprobes in parallel. -c. Kernel return probes for sparc64. -d. Support for other architectures. -e. User-space probes. +a. SystemTap (http://sourceware.org/systemtap): Provides a simplified +programming interface for probe-based instrumentation. Try it out. +b. Kernel return probes for sparc64. +c. Support for other architectures. +d. User-space probes. +e. Watchpoint probes (which fire on data references). 8. Kprobes Example @@ -411,8 +415,7 @@ int init_module(void) printk("Couldn't find %s to plant kprobe\n", "do_fork"); return -1; } - ret = register_kprobe(&kp); - if (ret < 0) { + if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); return -1; } -- cgit v0.10.2 From f822566165dd46ff5de9bf895cfa6c51f53bb0c4 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 14 Feb 2006 13:53:08 -0800 Subject: [PATCH] madvise MADV_DONTFORK/MADV_DOFORK Currently, copy-on-write may change the physical address of a page even if the user requested that the page is pinned in memory (either by mlock or by get_user_pages). This happens if the process forks meanwhile, and the parent writes to that page. As a result, the page is orphaned: in case of get_user_pages, the application will never see any data hardware DMA's into this page after the COW. In case of mlock'd memory, the parent is not getting the realtime/security benefits of mlock. In particular, this affects the Infiniband modules which do DMA from and into user pages all the time. This patch adds madvise options to control whether memory range is inherited across fork. Useful e.g. for when hardware is doing DMA from/into these pages. Could also be useful to an application wanting to speed up its forks by cutting large areas out of consideration. Signed-off-by: Michael S. Tsirkin Acked-by: Hugh Dickins Cc: Michael Kerrisk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h index f643953..a21515c 100644 --- a/include/asm-alpha/mman.h +++ b/include/asm-alpha/mman.h @@ -43,6 +43,8 @@ #define MADV_SPACEAVAIL 5 /* ensure resources are available */ #define MADV_DONTNEED 6 /* don't need these pages */ #define MADV_REMOVE 7 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-arm/mman.h b/include/asm-arm/mman.h index f0bebca..693ed85 100644 --- a/include/asm-arm/mman.h +++ b/include/asm-arm/mman.h @@ -36,6 +36,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-arm26/mman.h b/include/asm-arm26/mman.h index 0ed7780..2096c50 100644 --- a/include/asm-arm26/mman.h +++ b/include/asm-arm26/mman.h @@ -36,6 +36,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-cris/mman.h b/include/asm-cris/mman.h index 5a382b8..deddfb2 100644 --- a/include/asm-cris/mman.h +++ b/include/asm-cris/mman.h @@ -38,6 +38,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-frv/mman.h b/include/asm-frv/mman.h index 8af4a41..d3bca30 100644 --- a/include/asm-frv/mman.h +++ b/include/asm-frv/mman.h @@ -36,6 +36,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h index 744a8fb..ac0346f 100644 --- a/include/asm-h8300/mman.h +++ b/include/asm-h8300/mman.h @@ -36,6 +36,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-i386/mman.h b/include/asm-i386/mman.h index ba4941e..ab2339a 100644 --- a/include/asm-i386/mman.h +++ b/include/asm-i386/mman.h @@ -36,6 +36,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-ia64/mman.h b/include/asm-ia64/mman.h index 828beb2..357ebb7 100644 --- a/include/asm-ia64/mman.h +++ b/include/asm-ia64/mman.h @@ -44,6 +44,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-m32r/mman.h b/include/asm-m32r/mman.h index 12e2974..6b02fe3 100644 --- a/include/asm-m32r/mman.h +++ b/include/asm-m32r/mman.h @@ -38,6 +38,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h index ea262ab..efd12bc 100644 --- a/include/asm-m68k/mman.h +++ b/include/asm-m68k/mman.h @@ -36,6 +36,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-mips/mman.h b/include/asm-mips/mman.h index dd17c8b..6d01e26 100644 --- a/include/asm-mips/mman.h +++ b/include/asm-mips/mman.h @@ -66,6 +66,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-parisc/mman.h b/include/asm-parisc/mman.h index 736b0ab..a381cf5 100644 --- a/include/asm-parisc/mman.h +++ b/include/asm-parisc/mman.h @@ -49,6 +49,8 @@ #define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */ #define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */ #define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h index a2e34c2..fcff25d 100644 --- a/include/asm-powerpc/mman.h +++ b/include/asm-powerpc/mman.h @@ -45,6 +45,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-s390/mman.h b/include/asm-s390/mman.h index c8d5409..d41ca14 100644 --- a/include/asm-s390/mman.h +++ b/include/asm-s390/mman.h @@ -44,6 +44,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-sh/mman.h b/include/asm-sh/mman.h index 693bd55..0e08d05 100644 --- a/include/asm-sh/mman.h +++ b/include/asm-sh/mman.h @@ -36,6 +36,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h index 98435ad..4a298b2 100644 --- a/include/asm-sparc/mman.h +++ b/include/asm-sparc/mman.h @@ -55,6 +55,8 @@ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_FREE 0x5 /* (Solaris) contents can be freed */ #define MADV_REMOVE 0x6 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h index cb4b615..d705ec9 100644 --- a/include/asm-sparc64/mman.h +++ b/include/asm-sparc64/mman.h @@ -55,6 +55,8 @@ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_FREE 0x5 /* (Solaris) contents can be freed */ #define MADV_REMOVE 0x6 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-v850/mman.h b/include/asm-v850/mman.h index edc7996..7b851c3 100644 --- a/include/asm-v850/mman.h +++ b/include/asm-v850/mman.h @@ -33,6 +33,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-x86_64/mman.h b/include/asm-x86_64/mman.h index d0e97b7..b699a38 100644 --- a/include/asm-x86_64/mman.h +++ b/include/asm-x86_64/mman.h @@ -37,6 +37,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-xtensa/mman.h b/include/asm-xtensa/mman.h index 082a750..e2d7afb 100644 --- a/include/asm-xtensa/mman.h +++ b/include/asm-xtensa/mman.h @@ -73,6 +73,8 @@ #define MADV_WILLNEED 0x3 /* pre-fault pages */ #define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_REMOVE 0x5 /* remove these pages & resources */ +#define MADV_DONTFORK 0x30 /* dont inherit across fork */ +#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/mm/madvise.c b/mm/madvise.c index ae0ae3e..af3d573 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -22,16 +22,23 @@ static long madvise_behavior(struct vm_area_struct * vma, struct mm_struct * mm = vma->vm_mm; int error = 0; pgoff_t pgoff; - int new_flags = vma->vm_flags & ~VM_READHINTMASK; + int new_flags = vma->vm_flags; switch (behavior) { + case MADV_NORMAL: + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ; + break; case MADV_SEQUENTIAL: - new_flags |= VM_SEQ_READ; + new_flags = (new_flags & ~VM_RAND_READ) | VM_SEQ_READ; break; case MADV_RANDOM: - new_flags |= VM_RAND_READ; + new_flags = (new_flags & ~VM_SEQ_READ) | VM_RAND_READ; break; - default: + case MADV_DONTFORK: + new_flags |= VM_DONTCOPY; + break; + case MADV_DOFORK: + new_flags &= ~VM_DONTCOPY; break; } @@ -177,6 +184,12 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, long error; switch (behavior) { + case MADV_DOFORK: + if (vma->vm_flags & VM_IO) { + error = -EINVAL; + break; + } + case MADV_DONTFORK: case MADV_NORMAL: case MADV_SEQUENTIAL: case MADV_RANDOM: -- cgit v0.10.2 From d6077cb80cde4506720f9165eba99ee07438513f Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Tue, 14 Feb 2006 13:53:10 -0800 Subject: [PATCH] sched: revert "filter affine wakeups" Revert commit d7102e95b7b9c00277562c29aad421d2d521c5f6: [PATCH] sched: filter affine wakeups Apparently caused more than 10% performance regression for aim7 benchmark. The setup in use is 16-cpu HP rx8620, 64Gb of memory and 12 MSA1000s with 144 disks. Each disk is 72Gb with a single ext3 filesystem (courtesy of HP, who supplied benchmark results). The problem is, for aim7, the wake-up pattern is random, but it still needs load balancing action in the wake-up path to achieve best performance. With the above commit, lack of load balancing hurts that workload. However, for workloads like database transaction processing, the requirement is exactly opposite. In the wake up path, best performance is achieved with absolutely zero load balancing. We simply wake up the process on the CPU that it was previously run. Worst performance is obtained when we do load balancing at wake up. There isn't an easy way to auto detect the workload characteristics. Ingo's earlier patch that detects idle CPU and decide whether to load balance or not doesn't perform with aim7 either since all CPUs are busy (it causes even bigger perf. regression). Revert commit d7102e95b7b9c00277562c29aad421d2d521c5f6, which causes more than 10% performance regression with aim7. Signed-off-by: Ken Chen Acked-by: Ingo Molnar Cc: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/sched.h b/include/linux/sched.h index 9c1da02..b6f51e3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -697,12 +697,9 @@ struct task_struct { int lock_depth; /* BKL lock depth */ -#if defined(CONFIG_SMP) - int last_waker_cpu; /* CPU that last woke this task up */ -#if defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) int oncpu; #endif -#endif int prio, static_prio; struct list_head run_list; prio_array_t *array; diff --git a/kernel/sched.c b/kernel/sched.c index 87d93be..66d9572 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1204,9 +1204,6 @@ static int try_to_wake_up(task_t *p, unsigned int state, int sync) } } - if (p->last_waker_cpu != this_cpu) - goto out_set_cpu; - if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) goto out_set_cpu; @@ -1277,8 +1274,6 @@ out_set_cpu: cpu = task_cpu(p); } - p->last_waker_cpu = this_cpu; - out_activate: #endif /* CONFIG_SMP */ if (old_state == TASK_UNINTERRUPTIBLE) { @@ -1360,12 +1355,9 @@ void fastcall sched_fork(task_t *p, int clone_flags) #ifdef CONFIG_SCHEDSTATS memset(&p->sched_info, 0, sizeof(p->sched_info)); #endif -#if defined(CONFIG_SMP) - p->last_waker_cpu = cpu; -#if defined(__ARCH_WANT_UNLOCKED_CTXSW) +#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) p->oncpu = 0; #endif -#endif #ifdef CONFIG_PREEMPT /* Want to start with kernel preemption disabled. */ task_thread_info(p)->preempt_count = 1; -- cgit v0.10.2 From 5a1342f77304da8dc698e0ecf09925438764d80f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 14 Feb 2006 13:53:10 -0800 Subject: [PATCH] fix a typo in the CPU_H8300H dependencies Jean-Luc Leger found this obvious typo. Signed-off-by: Adrian Bunk Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu index a380167..582797d 100644 --- a/arch/h8300/Kconfig.cpu +++ b/arch/h8300/Kconfig.cpu @@ -169,7 +169,7 @@ endif config CPU_H8300H bool - depends on (H8002 || H83007 || H83048 || H83068) + depends on (H83002 || H83007 || H83048 || H83068) default y config CPU_H8S -- cgit v0.10.2 From e35a6619e7be59aa38249346327c89207663bb37 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 14 Feb 2006 13:53:14 -0800 Subject: [PATCH] s390: fix __delay implementation Fix __delay implementation. Called with an argument "1" or "0" it would loop nearly forever (since (1/2)-1 = 0xffffffff). Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index e96c35b..71f0a2f 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -30,7 +30,7 @@ void __delay(unsigned long loops) */ __asm__ __volatile__( "0: brct %0,0b" - : /* no outputs */ : "r" (loops/2) ); + : /* no outputs */ : "r" ((loops/2) + 1)); } /* -- cgit v0.10.2 From 06027bdd278a32a84b273e41db68a5db8ffd2bb6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 14 Feb 2006 13:53:15 -0800 Subject: [PATCH] hrtimer: round up relative start time on low-res arches CONFIG_TIME_LOW_RES is a temporary way for architectures to signal that they simply return xtime in do_gettimeoffset(). In this corner-case we want to round up by resolution when starting a relative timer, to avoid short timeouts. This will go away with the GTOD framework. Signed-off-by: Ingo Molnar Cc: Roman Zippel Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 60a617a..e083837 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -25,6 +25,10 @@ config GENERIC_HARDIRQS bool default n +config TIME_LOW_RES + bool + default y + mainmenu "Fujitsu FR-V Kernel Configuration" source "init/Kconfig" diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 80940d7..98308b0 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -33,6 +33,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config TIME_LOW_RES + bool + default y + config ISA bool default y diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 96b9198..8849439 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -21,6 +21,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config TIME_LOW_RES + bool + default y + config ARCH_MAY_HAVE_PC_FDC bool depends on Q40 || (BROKEN && SUN3X) diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index e2a6e86..e50858d 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -29,6 +29,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config TIME_LOW_RES + bool + default y + source "init/Kconfig" menu "Processor type and features" diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 7c914a4..eca33cf 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -29,6 +29,11 @@ config GENERIC_CALIBRATE_DELAY bool default y +config TIME_LOW_RES + bool + depends on SMP + default y + config GENERIC_ISA_DMA bool diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig index 0449463..e7fc3e5 100644 --- a/arch/v850/Kconfig +++ b/arch/v850/Kconfig @@ -28,6 +28,10 @@ config GENERIC_IRQ_PROBE bool default y +config TIME_LOW_RES + bool + default y + # Turn off some random 386 crap that can affect device config config ISA bool diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 2b6e175..5ae51f1 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -418,8 +418,19 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) /* Switch the timer base, if necessary: */ new_base = switch_hrtimer_base(timer, base); - if (mode == HRTIMER_REL) + if (mode == HRTIMER_REL) { tim = ktime_add(tim, new_base->get_time()); + /* + * CONFIG_TIME_LOW_RES is a temporary way for architectures + * to signal that they simply return xtime in + * do_gettimeoffset(). In this case we want to round up by + * resolution when starting a relative timer, to avoid short + * timeouts. This will go away with the GTOD framework. + */ +#ifdef CONFIG_TIME_LOW_RES + tim = ktime_add(tim, base->resolution); +#endif + } timer->expires = tim; enqueue_hrtimer(timer, new_base); -- cgit v0.10.2 From 68f624fc8b9fa50de9cc0ebd612ef7b7b9fa32d0 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 14 Feb 2006 13:53:18 -0800 Subject: [PATCH] FRV: Miscellaneous fixes Make various alterations and fixes to the FRV arch: (1) Resyncs the FRV system call collection with the i386 arch. (2) Discards __iounmap() as it's not used. (3) Fixes the use of the SWAP/SWAPI instruction to get the arguments the right way around in atomic.h, and also to get the asm constraints correct. (4) Moves copy_to/from_user_page() to asm/cacheflush.h to be consistent with other archs. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 5f65483..c69d499 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1418,11 +1418,27 @@ sys_call_table: .long sys_add_key .long sys_request_key .long sys_keyctl - .long sys_ni_syscall // sys_vperfctr_open - .long sys_ni_syscall // sys_vperfctr_control /* 290 */ - .long sys_ni_syscall // sys_vperfctr_unlink - .long sys_ni_syscall // sys_vperfctr_iresume - .long sys_ni_syscall // sys_vperfctr_read + .long sys_ioprio_set + .long sys_ioprio_get /* 290 */ + .long sys_inotify_init + .long sys_inotify_add_watch + .long sys_inotify_rm_watch + .long sys_migrate_pages + .long sys_openat /* 295 */ + .long sys_mkdirat + .long sys_mknodat + .long sys_fchownat + .long sys_futimesat + .long sys_newfstatat /* 300 */ + .long sys_unlinkat + .long sys_renameat + .long sys_linkat + .long sys_symlinkat + .long sys_readlinkat /* 305 */ + .long sys_fchmodat + .long sys_faccessat + .long sys_pselect6 + .long sys_ppoll syscall_table_size = (. - sys_call_table) diff --git a/arch/frv/mm/kmap.c b/arch/frv/mm/kmap.c index 539f45e6..c54f18e 100644 --- a/arch/frv/mm/kmap.c +++ b/arch/frv/mm/kmap.c @@ -44,15 +44,6 @@ void iounmap(void *addr) } /* - * __iounmap unmaps nearly everything, so be careful - * it doesn't free currently pointer/page tables anymore but it - * wans't used anyway and might be added later. - */ -void __iounmap(void *addr, unsigned long size) -{ -} - -/* * Set new cache mode for some kernel address space. * The caller must push data for that range itself, if such data may already * be in the cache. diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h index a59f684..5d9f84b 100644 --- a/include/asm-frv/atomic.h +++ b/include/asm-frv/atomic.h @@ -220,9 +220,9 @@ extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsig switch (sizeof(__xg_orig)) { \ case 4: \ asm volatile( \ - "swap%I0 %2,%M0" \ - : "+m"(*__xg_ptr), "=&r"(__xg_orig) \ - : "r"(x) \ + "swap%I0 %M0,%1" \ + : "+m"(*__xg_ptr), "=r"(__xg_orig) \ + : "1"(x) \ : "memory" \ ); \ break; \ diff --git a/include/asm-frv/cacheflush.h b/include/asm-frv/cacheflush.h index 3007dec..eaa5826 100644 --- a/include/asm-frv/cacheflush.h +++ b/include/asm-frv/cacheflush.h @@ -87,5 +87,17 @@ static inline void flush_icache_page(struct vm_area_struct *vma, struct page *pa flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE); } +/* + * permit ptrace to access another process's address space through the icache + * and the dcache + */ +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ +do { \ + memcpy((dst), (src), (len)); \ + flush_icache_user_range((vma), (page), (vaddr), (len)); \ +} while(0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy((dst), (src), (len)) #endif /* _ASM_CACHEFLUSH_H */ diff --git a/include/asm-frv/io.h b/include/asm-frv/io.h index 075369b..01247cb 100644 --- a/include/asm-frv/io.h +++ b/include/asm-frv/io.h @@ -251,7 +251,6 @@ static inline void writel(uint32_t datum, volatile void __iomem *addr) #define IOMAP_WRITETHROUGH 3 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); -extern void __iounmap(void __iomem *addr, unsigned long size); static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) { diff --git a/include/asm-frv/uaccess.h b/include/asm-frv/uaccess.h index b6bcbe0..a1d1404 100644 --- a/include/asm-frv/uaccess.h +++ b/include/asm-frv/uaccess.h @@ -306,7 +306,4 @@ extern long strnlen_user(const char *src, long count); extern unsigned long search_exception_table(unsigned long addr); -#define copy_to_user_page(vma, page, vaddr, dst, src, len) memcpy(dst, src, len) -#define copy_from_user_page(vma, page, vaddr, dst, src, len) memcpy(dst, src, len) - #endif /* _ASM_UACCESS_H */ diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h index 4d994d2..322531c 100644 --- a/include/asm-frv/unistd.h +++ b/include/asm-frv/unistd.h @@ -295,13 +295,29 @@ #define __NR_add_key 286 #define __NR_request_key 287 #define __NR_keyctl 288 -#define __NR_vperfctr_open 289 -#define __NR_vperfctr_control (__NR_perfctr_info+1) -#define __NR_vperfctr_unlink (__NR_perfctr_info+2) -#define __NR_vperfctr_iresume (__NR_perfctr_info+3) -#define __NR_vperfctr_read (__NR_perfctr_info+4) +#define __NR_ioprio_set 289 +#define __NR_ioprio_get 290 +#define __NR_inotify_init 291 +#define __NR_inotify_add_watch 292 +#define __NR_inotify_rm_watch 293 +#define __NR_migrate_pages 294 +#define __NR_openat 295 +#define __NR_mkdirat 296 +#define __NR_mknodat 297 +#define __NR_fchownat 298 +#define __NR_futimesat 299 +#define __NR_newfstatat 300 +#define __NR_unlinkat 301 +#define __NR_renameat 302 +#define __NR_linkat 303 +#define __NR_symlinkat 304 +#define __NR_readlinkat 305 +#define __NR_fchmodat 306 +#define __NR_faccessat 307 +#define __NR_pselect6 308 +#define __NR_ppoll 309 -#define NR_syscalls 294 +#define NR_syscalls 310 /* * process the return value of a syscall, consigning it to one of two possible fates -- cgit v0.10.2 From 28baebae73c3ea8b75c7cae225a7db817ab825a9 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 14 Feb 2006 13:53:20 -0800 Subject: [PATCH] FRV: Use virtual interrupt disablement Make the FRV arch use virtual interrupt disablement because accesses to the processor status register (PSR) are relatively slow and because we will soon have the need to deal with multiple interrupt controls at the same time (separate h/w and inter-core interrupts). The way this is done is to dedicate one of the four integer condition code registers (ICC2) to maintaining a virtual interrupt disablement state whilst inside the kernel. This uses the ICC2.Z flag (Zero) to indicate whether the interrupts are virtually disabled and the ICC2.C flag (Carry) to indicate whether the interrupts are physically disabled. ICC2.Z is set to indicate interrupts are virtually disabled. ICC2.C is set to indicate interrupts are physically enabled. Under normal running conditions Z==0 and C==1. Disabling interrupts with local_irq_disable() doesn't then actually physically disable interrupts - it merely sets ICC2.Z to 1. Should an interrupt then happen, the exception prologue will note ICC2.Z is set and branch out of line using one instruction (an unlikely BEQ). Here it will physically disable interrupts and clear ICC2.C. When it comes time to enable interrupts (local_irq_enable()), this simply clears the ICC2.Z flag and invokes a trap #2 if both Z and C flags are clear (the HI integer condition). This can be done with the TIHI conditional trap instruction. The trap then physically reenables interrupts and sets ICC2.C again. Upon returning the interrupt will be taken as interrupts will then be enabled. Note that whilst processing the trap, the whole exceptions system is disabled, and so an interrupt can't happen till it returns. If no pending interrupt had happened, ICC2.C would still be set, the HI condition would not be fulfilled, and no trap will happen. Saving interrupts (local_irq_save) is simply a matter of pulling the ICC2.Z flag out of the CCR register, shifting it down and masking it off. This gives a result of 0 if interrupts were enabled and 1 if they weren't. Restoring interrupts (local_irq_restore) is then a matter of taking the saved value mentioned previously and XOR'ing it against 1. If it was one, the result will be zero, and if it was zero the result will be non-zero. This result is then used to affect the ICC2.Z flag directly (it is a condition code flag after all). An XOR instruction does not affect the Carry flag, and so that bit of state is unchanged. The two flags can then be sampled to see if they're both zero using the trap (TIHI) as for the unconditional reenablement (local_irq_enable). This patch also: (1) Modifies the debugging stub (break.S) to handle single-stepping crossing into the trap #2 handler and into virtually disabled interrupts. (2) Removes superseded fixup pointers from the second instructions in the trap tables (there's no a separate fixup table for this). (3) Declares the trap #3 vector for use in .org directives in the trap table. (4) Moves irq_enter() and irq_exit() in do_IRQ() to avoid problems with virtual interrupt handling, and removes the duplicate code that has now been folded into irq_exit() (softirq and preemption handling). (5) Tells the compiler in the arch Makefile that ICC2 is now reserved. (6) Documents the in-kernel ABI, including the virtual interrupts. (7) Renames the old irq management functions to different names. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/fujitsu/frv/kernel-ABI.txt b/Documentation/fujitsu/frv/kernel-ABI.txt new file mode 100644 index 0000000..0ed9b0a --- /dev/null +++ b/Documentation/fujitsu/frv/kernel-ABI.txt @@ -0,0 +1,234 @@ + ================================= + INTERNAL KERNEL ABI FOR FR-V ARCH + ================================= + +The internal FRV kernel ABI is not quite the same as the userspace ABI. A number of the registers +are used for special purposed, and the ABI is not consistent between modules vs core, and MMU vs +no-MMU. + +This partly stems from the fact that FRV CPUs do not have a separate supervisor stack pointer, and +most of them do not have any scratch registers, thus requiring at least one general purpose +register to be clobbered in such an event. Also, within the kernel core, it is possible to simply +jump or call directly between functions using a relative offset. This cannot be extended to modules +for the displacement is likely to be too far. Thus in modules the address of a function to call +must be calculated in a register and then used, requiring two extra instructions. + +This document has the following sections: + + (*) System call register ABI + (*) CPU operating modes + (*) Internal kernel-mode register ABI + (*) Internal debug-mode register ABI + (*) Virtual interrupt handling + + +======================== +SYSTEM CALL REGISTER ABI +======================== + +When a system call is made, the following registers are effective: + + REGISTERS CALL RETURN + =============== ======================= ======================= + GR7 System call number Preserved + GR8 Syscall arg #1 Return value + GR9-GR13 Syscall arg #2-6 Preserved + + +=================== +CPU OPERATING MODES +=================== + +The FR-V CPU has three basic operating modes. In order of increasing capability: + + (1) User mode. + + Basic userspace running mode. + + (2) Kernel mode. + + Normal kernel mode. There are many additional control registers available that may be + accessed in this mode, in addition to all the stuff available to user mode. This has two + submodes: + + (a) Exceptions enabled (PSR.T == 1). + + Exceptions will invoke the appropriate normal kernel mode handler. On entry to the + handler, the PSR.T bit will be cleared. + + (b) Exceptions disabled (PSR.T == 0). + + No exceptions or interrupts may happen. Any mandatory exceptions will cause the CPU to + halt unless the CPU is told to jump into debug mode instead. + + (3) Debug mode. + + No exceptions may happen in this mode. Memory protection and management exceptions will be + flagged for later consideration, but the exception handler won't be invoked. Debugging traps + such as hardware breakpoints and watchpoints will be ignored. This mode is entered only by + debugging events obtained from the other two modes. + + All kernel mode registers may be accessed, plus a few extra debugging specific registers. + + +================================= +INTERNAL KERNEL-MODE REGISTER ABI +================================= + +There are a number of permanent register assignments that are set up by entry.S in the exception +prologue. Note that there is a complete set of exception prologues for each of user->kernel +transition and kernel->kernel transition. There are also user->debug and kernel->debug mode +transition prologues. + + + REGISTER FLAVOUR USE + =============== ======= ==================================================== + GR1 Supervisor stack pointer + GR15 Current thread info pointer + GR16 GP-Rel base register for small data + GR28 Current exception frame pointer (__frame) + GR29 Current task pointer (current) + GR30 Destroyed by kernel mode entry + GR31 NOMMU Destroyed by debug mode entry + GR31 MMU Destroyed by TLB miss kernel mode entry + CCR.ICC2 Virtual interrupt disablement tracking + CCCR.CC3 Cleared by exception prologue (atomic op emulation) + SCR0 MMU See mmu-layout.txt. + SCR1 MMU See mmu-layout.txt. + SCR2 MMU Save for EAR0 (destroyed by icache insns in debug mode) + SCR3 MMU Save for GR31 during debug exceptions + DAMR/IAMR NOMMU Fixed memory protection layout. + DAMR/IAMR MMU See mmu-layout.txt. + + +Certain registers are also used or modified across function calls: + + REGISTER CALL RETURN + =============== =============================== =============================== + GR0 Fixed Zero - + GR2 Function call frame pointer + GR3 Special Preserved + GR3-GR7 - Clobbered + GR8 Function call arg #1 Return value (or clobbered) + GR9 Function call arg #2 Return value MSW (or clobbered) + GR10-GR13 Function call arg #3-#6 Clobbered + GR14 - Clobbered + GR15-GR16 Special Preserved + GR17-GR27 - Preserved + GR28-GR31 Special Only accessed explicitly + LR Return address after CALL Clobbered + CCR/CCCR - Mostly Clobbered + + +================================ +INTERNAL DEBUG-MODE REGISTER ABI +================================ + +This is the same as the kernel-mode register ABI for functions calls. The difference is that in +debug-mode there's a different stack and a different exception frame. Almost all the global +registers from kernel-mode (including the stack pointer) may be changed. + + REGISTER FLAVOUR USE + =============== ======= ==================================================== + GR1 Debug stack pointer + GR16 GP-Rel base register for small data + GR31 Current debug exception frame pointer (__debug_frame) + SCR3 MMU Saved value of GR31 + + +Note that debug mode is able to interfere with the kernel's emulated atomic ops, so it must be +exceedingly careful not to do any that would interact with the main kernel in this regard. Hence +the debug mode code (gdbstub) is almost completely self-contained. The only external code used is +the sprintf family of functions. + +Futhermore, break.S is so complicated because single-step mode does not switch off on entry to an +exception. That means unless manually disabled, single-stepping will blithely go on stepping into +things like interrupts. See gdbstub.txt for more information. + + +========================== +VIRTUAL INTERRUPT HANDLING +========================== + +Because accesses to the PSR is so slow, and to disable interrupts we have to access it twice (once +to read and once to write), we don't actually disable interrupts at all if we don't have to. What +we do instead is use the ICC2 condition code flags to note virtual disablement, such that if we +then do take an interrupt, we note the flag, really disable interrupts, set another flag and resume +execution at the point the interrupt happened. Setting condition flags as a side effect of an +arithmetic or logical instruction is really fast. This use of the ICC2 only occurs within the +kernel - it does not affect userspace. + +The flags we use are: + + (*) CCR.ICC2.Z [Zero flag] + + Set to virtually disable interrupts, clear when interrupts are virtually enabled. Can be + modified by logical instructions without affecting the Carry flag. + + (*) CCR.ICC2.C [Carry flag] + + Clear to indicate hardware interrupts are really disabled, set otherwise. + + +What happens is this: + + (1) Normal kernel-mode operation. + + ICC2.Z is 0, ICC2.C is 1. + + (2) An interrupt occurs. The exception prologue examines ICC2.Z and determines that nothing needs + doing. This is done simply with an unlikely BEQ instruction. + + (3) The interrupts are disabled (local_irq_disable) + + ICC2.Z is set to 1. + + (4) If interrupts were then re-enabled (local_irq_enable): + + ICC2.Z would be set to 0. + + A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would be used to trap if + interrupts were now virtually enabled, but physically disabled - which they're not, so the + trap isn't taken. The kernel would then be back to state (1). + + (5) An interrupt occurs. The exception prologue examines ICC2.Z and determines that the interrupt + shouldn't actually have happened. It jumps aside, and there disabled interrupts by setting + PSR.PIL to 14 and then it clears ICC2.C. + + (6) If interrupts were then saved and disabled again (local_irq_save): + + ICC2.Z would be shifted into the save variable and masked off (giving a 1). + + ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be unaffected (ie: 0). + + (7) If interrupts were then restored from state (6) (local_irq_restore): + + ICC2.Z would be set to indicate the result of XOR'ing the saved value (ie: 1) with 1, which + gives a result of 0 - thus leaving ICC2.Z set. + + ICC2.C would remain unaffected (ie: 0). + + A TIHI #2 instruction would be used to again assay the current state, but this would do + nothing as Z==1. + + (8) If interrupts were then enabled (local_irq_enable): + + ICC2.Z would be cleared. ICC2.C would be left unaffected. Both flags would now be 0. + + A TIHI #2 instruction again issued to assay the current state would then trap as both Z==0 + [interrupts virtually enabled] and C==0 [interrupts really disabled] would then be true. + + (9) The trap #2 handler would simply enable hardware interrupts (set PSR.PIL to 0), set ICC2.C to + 1 and return. + +(10) Immediately upon returning, the pending interrupt would be taken. + +(11) The interrupt handler would take the path of actually processing the interrupt (ICC2.Z is + clear, BEQ fails as per step (2)). + +(12) The interrupt handler would then set ICC2.C to 1 since hardware interrupts are definitely + enabled - or else the kernel wouldn't be here. + +(13) On return from the interrupt handler, things would be back to state (1). + +This trap (#2) is only available in kernel mode. In user mode it will result in SIGILL. diff --git a/arch/frv/Makefile b/arch/frv/Makefile index 90c0fb8..d163747 100644 --- a/arch/frv/Makefile +++ b/arch/frv/Makefile @@ -81,7 +81,7 @@ endif # - reserve CC3 for use with atomic ops # - all the extra registers are dealt with only at context switch time CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media -CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 +CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2 AFLAGS += -mno-fdpic ASFLAGS += -mno-fdpic diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S index 33233dc..687c48d 100644 --- a/arch/frv/kernel/break.S +++ b/arch/frv/kernel/break.S @@ -200,12 +200,20 @@ __break_step: movsg bpcsr,gr2 sethi.p %hi(__entry_kernel_external_interrupt),gr3 setlo %lo(__entry_kernel_external_interrupt),gr3 - subcc gr2,gr3,gr0,icc0 + subcc.p gr2,gr3,gr0,icc0 + sethi %hi(__entry_uspace_external_interrupt),gr3 + setlo.p %lo(__entry_uspace_external_interrupt),gr3 beq icc0,#2,__break_step_kernel_external_interrupt - sethi.p %hi(__entry_uspace_external_interrupt),gr3 - setlo %lo(__entry_uspace_external_interrupt),gr3 - subcc gr2,gr3,gr0,icc0 + subcc.p gr2,gr3,gr0,icc0 + sethi %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3 + setlo.p %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3 beq icc0,#2,__break_step_uspace_external_interrupt + subcc.p gr2,gr3,gr0,icc0 + sethi %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3 + setlo.p %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3 + beq icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled + subcc gr2,gr3,gr0,icc0 + beq icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable LEDS 0x2007,gr2 @@ -254,6 +262,9 @@ __break_step_kernel_softprog_interrupt: # step through an external interrupt from kernel mode .globl __break_step_kernel_external_interrupt __break_step_kernel_external_interrupt: + # deal with virtual interrupt disablement + beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled + sethi.p %hi(__entry_kernel_external_interrupt_reentry),gr3 setlo %lo(__entry_kernel_external_interrupt_reentry),gr3 @@ -294,6 +305,64 @@ __break_return_as_kernel_prologue: #endif rett #1 +# we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled +# need to really disable interrupts, set flag, fix up and return +__break_step_kernel_external_interrupt_virtually_disabled: + movsg psr,gr2 + andi gr2,#~PSR_PIL,gr2 + ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */ + movgs gr2,psr + + ldi @(gr31,#REG_CCR),gr3 + movgs gr3,ccr + subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */ + + # exceptions must've been enabled and we must've been in supervisor mode + setlos BPSR_BET|BPSR_BS,gr3 + movgs gr3,bpsr + + # return to where the interrupt happened + movsg pcsr,gr2 + movgs gr2,bpcsr + + lddi.p @(gr31,#REG_GR(2)),gr2 + + xor gr31,gr31,gr31 + movgs gr0,brr +#ifdef CONFIG_MMU + movsg scr3,gr31 +#endif + rett #1 + +# we stepped through into the virtual interrupt reenablement trap +# +# we also want to single step anyway, but after fixing up so that we get an event on the +# instruction after the broken-into exception returns + .globl __break_step_kernel_external_interrupt_virtual_reenable +__break_step_kernel_external_interrupt_virtual_reenable: + movsg psr,gr2 + andi gr2,#~PSR_PIL,gr2 + movgs gr2,psr + + ldi @(gr31,#REG_CCR),gr3 + movgs gr3,ccr + subicc gr0,#1,gr0,icc2 /* clear Z, set C */ + + # save the adjusted ICC2 + movsg ccr,gr3 + sti gr3,@(gr31,#REG_CCR) + + # exceptions must've been enabled and we must've been in supervisor mode + setlos BPSR_BET|BPSR_BS,gr3 + movgs gr3,bpsr + + # return to where the trap happened + movsg pcsr,gr2 + movgs gr2,bpcsr + + # and then process the single step + bra __break_continue + # step through an internal exception from uspace mode .globl __break_step_uspace_softprog_interrupt __break_step_uspace_softprog_interrupt: diff --git a/arch/frv/kernel/entry-table.S b/arch/frv/kernel/entry-table.S index 9b9243e..81568ac 100644 --- a/arch/frv/kernel/entry-table.S +++ b/arch/frv/kernel/entry-table.S @@ -116,6 +116,8 @@ __break_kerneltrap_fixup_table: .long __break_step_uspace_external_interrupt .section .trap.kernel .org \tbr_tt + # deal with virtual interrupt disablement + beq icc2,#0,__entry_kernel_external_interrupt_virtually_disabled bra __entry_kernel_external_interrupt .section .trap.fixup.kernel .org \tbr_tt >> 2 @@ -259,25 +261,52 @@ __trap_fixup_kernel_data_tlb_miss: .org TBR_TT_TRAP0 .rept 127 bra __entry_uspace_softprog_interrupt - bra __break_step_uspace_softprog_interrupt - .long 0,0 + .long 0,0,0 .endr .org TBR_TT_BREAK bra __entry_break .long 0,0,0 + .section .trap.fixup.user + .org TBR_TT_TRAP0 >> 2 + .rept 127 + .long __break_step_uspace_softprog_interrupt + .endr + .org TBR_TT_BREAK >> 2 + .long 0 + # miscellaneous kernel mode entry points .section .trap.kernel .org TBR_TT_TRAP0 - .rept 127 bra __entry_kernel_softprog_interrupt - bra __break_step_kernel_softprog_interrupt - .long 0,0 + .org TBR_TT_TRAP1 + bra __entry_kernel_softprog_interrupt + + # trap #2 in kernel - reenable interrupts + .org TBR_TT_TRAP2 + bra __entry_kernel_external_interrupt_virtual_reenable + + # miscellaneous kernel traps + .org TBR_TT_TRAP3 + .rept 124 + bra __entry_kernel_softprog_interrupt + .long 0,0,0 .endr .org TBR_TT_BREAK bra __entry_break .long 0,0,0 + .section .trap.fixup.kernel + .org TBR_TT_TRAP0 >> 2 + .long __break_step_kernel_softprog_interrupt + .long __break_step_kernel_softprog_interrupt + .long __break_step_kernel_external_interrupt_virtual_reenable + .rept 124 + .long __break_step_kernel_softprog_interrupt + .endr + .org TBR_TT_BREAK >> 2 + .long 0 + # miscellaneous debug mode entry points .section .trap.break .org TBR_TT_BREAK diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index c69d499..1d21c8d 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -141,7 +141,10 @@ __entry_uspace_external_interrupt_reentry: movsg gner0,gr4 movsg gner1,gr5 - stdi gr4,@(gr28,#REG_GNER0) + stdi.p gr4,@(gr28,#REG_GNER0) + + # interrupts start off fully disabled in the interrupt handler + subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ # set up kernel global registers sethi.p %hi(__kernel_current_task),gr5 @@ -193,9 +196,8 @@ __entry_uspace_external_interrupt_reentry: .type __entry_kernel_external_interrupt,@function __entry_kernel_external_interrupt: LEDS 0x6210 - - sub sp,gr15,gr31 - LEDS32 +// sub sp,gr15,gr31 +// LEDS32 # set up the stack pointer or.p sp,gr0,gr30 @@ -231,7 +233,10 @@ __entry_kernel_external_interrupt_reentry: stdi gr24,@(gr28,#REG_GR(24)) stdi gr26,@(gr28,#REG_GR(26)) sti gr29,@(gr28,#REG_GR(29)) - stdi gr30,@(gr28,#REG_GR(30)) + stdi.p gr30,@(gr28,#REG_GR(30)) + + # note virtual interrupts will be fully enabled upon return + subicc gr0,#1,gr0,icc2 /* clear Z, set C */ movsg tbr ,gr20 movsg psr ,gr22 @@ -267,7 +272,10 @@ __entry_kernel_external_interrupt_reentry: movsg gner0,gr4 movsg gner1,gr5 - stdi gr4,@(gr28,#REG_GNER0) + stdi.p gr4,@(gr28,#REG_GNER0) + + # interrupts start off fully disabled in the interrupt handler + subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ # set the return address sethi.p %hi(__entry_return_from_kernel_interrupt),gr4 @@ -291,6 +299,45 @@ __entry_kernel_external_interrupt_reentry: .size __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt +############################################################################### +# +# deal with interrupts that were actually virtually disabled +# - we need to really disable them, flag the fact and return immediately +# - if you change this, you must alter break.S also +# +############################################################################### + .balign L1_CACHE_BYTES + .globl __entry_kernel_external_interrupt_virtually_disabled + .type __entry_kernel_external_interrupt_virtually_disabled,@function +__entry_kernel_external_interrupt_virtually_disabled: + movsg psr,gr30 + andi gr30,#~PSR_PIL,gr30 + ori gr30,#PSR_PIL_14,gr30 ; debugging interrupts only + movgs gr30,psr + subcc gr0,gr0,gr0,icc2 ; leave Z set, clear C + rett #0 + + .size __entry_kernel_external_interrupt_virtually_disabled,.-__entry_kernel_external_interrupt_virtually_disabled + +############################################################################### +# +# deal with re-enablement of interrupts that were pending when virtually re-enabled +# - set ICC2.C, re-enable the real interrupts and return +# - we can clear ICC2.Z because we shouldn't be here if it's not 0 [due to TIHI] +# - if you change this, you must alter break.S also +# +############################################################################### + .balign L1_CACHE_BYTES + .globl __entry_kernel_external_interrupt_virtual_reenable + .type __entry_kernel_external_interrupt_virtual_reenable,@function +__entry_kernel_external_interrupt_virtual_reenable: + movsg psr,gr30 + andi gr30,#~PSR_PIL,gr30 ; re-enable interrupts + movgs gr30,psr + subicc gr0,#1,gr0,icc2 ; clear Z, set C + rett #0 + + .size __entry_kernel_external_interrupt_virtual_reenable,.-__entry_kernel_external_interrupt_virtual_reenable ############################################################################### # @@ -335,6 +382,7 @@ __entry_uspace_softprog_interrupt_reentry: sethi.p %hi(__entry_return_from_user_exception),gr23 setlo %lo(__entry_return_from_user_exception),gr23 + bra __entry_common .size __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt @@ -495,7 +543,10 @@ __entry_common: movsg gner0,gr4 movsg gner1,gr5 - stdi gr4,@(gr28,#REG_GNER0) + stdi.p gr4,@(gr28,#REG_GNER0) + + # set up virtual interrupt disablement + subicc gr0,#1,gr0,icc2 /* clear Z flag, set C flag */ # set up kernel global registers sethi.p %hi(__kernel_current_task),gr5 diff --git a/arch/frv/kernel/head.S b/arch/frv/kernel/head.S index c73b4fe..29a5265 100644 --- a/arch/frv/kernel/head.S +++ b/arch/frv/kernel/head.S @@ -513,6 +513,9 @@ __head_mmu_enabled: movgs gr0,ccr movgs gr0,cccr + # initialise the virtual interrupt handling + subcc gr0,gr0,gr0,icc2 /* set Z, clear C */ + #ifdef CONFIG_MMU movgs gr3,scr2 movgs gr3,scr3 diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c index 59580c5..27ab4c3 100644 --- a/arch/frv/kernel/irq.c +++ b/arch/frv/kernel/irq.c @@ -287,18 +287,11 @@ asmlinkage void do_IRQ(void) struct irq_source *source; int level, cpu; + irq_enter(); + level = (__frame->tbr >> 4) & 0xf; cpu = smp_processor_id(); -#if 0 - { - static u32 irqcount; - *(volatile u32 *) 0xe1200004 = ~((irqcount++ << 8) | level); - *(volatile u16 *) 0xffc00100 = (u16) ~0x9999; - mb(); - } -#endif - if ((unsigned long) __frame - (unsigned long) (current + 1) < 512) BUG(); @@ -308,40 +301,12 @@ asmlinkage void do_IRQ(void) kstat_this_cpu.irqs[level]++; - irq_enter(); - for (source = frv_irq_levels[level].sources; source; source = source->next) source->doirq(source); - irq_exit(); - __clr_MASK(level); - /* only process softirqs if we didn't interrupt another interrupt handler */ - if ((__frame->psr & PSR_PIL) == PSR_PIL_0) - if (local_softirq_pending()) - do_softirq(); - -#ifdef CONFIG_PREEMPT - local_irq_disable(); - while (--current->preempt_count == 0) { - if (!(__frame->psr & PSR_S) || - current->need_resched == 0 || - in_interrupt()) - break; - current->preempt_count++; - local_irq_enable(); - preempt_schedule(); - local_irq_disable(); - } -#endif - -#if 0 - { - *(volatile u16 *) 0xffc00100 = (u16) ~0x6666; - mb(); - } -#endif + irq_exit(); } /* end do_IRQ() */ diff --git a/include/asm-frv/spr-regs.h b/include/asm-frv/spr-regs.h index ef472f0..c2a541e 100644 --- a/include/asm-frv/spr-regs.h +++ b/include/asm-frv/spr-regs.h @@ -98,6 +98,7 @@ #define TBR_TT_TRAP0 (0x80 << 4) #define TBR_TT_TRAP1 (0x81 << 4) #define TBR_TT_TRAP2 (0x82 << 4) +#define TBR_TT_TRAP3 (0x83 << 4) #define TBR_TT_TRAP126 (0xfe << 4) #define TBR_TT_BREAK (0xff << 4) diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h index d2aea70..f72ff0c 100644 --- a/include/asm-frv/system.h +++ b/include/asm-frv/system.h @@ -40,8 +40,84 @@ do { \ /* * interrupt flag manipulation + * - use virtual interrupt management since touching the PSR is slow + * - ICC2.Z: T if interrupts virtually disabled + * - ICC2.C: F if interrupts really disabled + * - if Z==1 upon interrupt: + * - C is set to 0 + * - interrupts are really disabled + * - entry.S returns immediately + * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts + * - if taken, the trap: + * - sets ICC2.C + * - enables interrupts */ -#define local_irq_disable() \ +#define local_irq_disable() \ +do { \ + /* set Z flag, but don't change the C flag */ \ + asm volatile(" andcc gr0,gr0,gr0,icc2 \n" \ + : \ + : \ + : "memory", "icc2" \ + ); \ +} while(0) + +#define local_irq_enable() \ +do { \ + /* clear Z flag and then test the C flag */ \ + asm volatile(" oricc gr0,#1,gr0,icc2 \n" \ + " tihi icc2,gr0,#2 \n" \ + : \ + : \ + : "memory", "icc2" \ + ); \ +} while(0) + +#define local_save_flags(flags) \ +do { \ + typecheck(unsigned long, flags); \ + asm volatile("movsg ccr,%0" \ + : "=r"(flags) \ + : \ + : "memory"); \ + \ + /* shift ICC2.Z to bit 0 */ \ + flags >>= 26; \ + \ + /* make flags 1 if interrupts disabled, 0 otherwise */ \ + flags &= 1UL; \ +} while(0) + +#define irqs_disabled() \ + ({unsigned long flags; local_save_flags(flags); flags; }) + +#define local_irq_save(flags) \ +do { \ + typecheck(unsigned long, flags); \ + local_save_flags(flags); \ + local_irq_disable(); \ +} while(0) + +#define local_irq_restore(flags) \ +do { \ + typecheck(unsigned long, flags); \ + \ + /* load the Z flag by turning 1 if disabled into 0 if disabled \ + * and thus setting the Z flag but not the C flag */ \ + asm volatile(" xoricc %0,#1,gr0,icc2 \n" \ + /* then test Z=0 and C=0 */ \ + " tihi icc2,gr0,#2 \n" \ + : \ + : "r"(flags) \ + : "memory", "icc2" \ + ); \ + \ +} while(0) + +/* + * real interrupt flag manipulation + */ +#define __local_irq_disable() \ do { \ unsigned long psr; \ asm volatile(" movsg psr,%0 \n" \ @@ -53,7 +129,7 @@ do { \ : "memory"); \ } while(0) -#define local_irq_enable() \ +#define __local_irq_enable() \ do { \ unsigned long psr; \ asm volatile(" movsg psr,%0 \n" \ @@ -64,7 +140,7 @@ do { \ : "memory"); \ } while(0) -#define local_save_flags(flags) \ +#define __local_save_flags(flags) \ do { \ typecheck(unsigned long, flags); \ asm("movsg psr,%0" \ @@ -73,7 +149,7 @@ do { \ : "memory"); \ } while(0) -#define local_irq_save(flags) \ +#define __local_irq_save(flags) \ do { \ unsigned long npsr; \ typecheck(unsigned long, flags); \ @@ -86,7 +162,7 @@ do { \ : "memory"); \ } while(0) -#define local_irq_restore(flags) \ +#define __local_irq_restore(flags) \ do { \ typecheck(unsigned long, flags); \ asm volatile(" movgs %0,psr \n" \ @@ -95,7 +171,7 @@ do { \ : "memory"); \ } while(0) -#define irqs_disabled() \ +#define __irqs_disabled() \ ((__get_PSR() & PSR_PIL) >= PSR_PIL_14) /* -- cgit v0.10.2 From 581141cb4b10ebd865dcb7b80f5e712e2def5408 Mon Sep 17 00:00:00 2001 From: "Albert D. Cahalan" Date: Tue, 14 Feb 2006 13:53:20 -0800 Subject: [PATCH] x86: document sysenter path This path isn't obvious. It looks as if the kernel will be taking three args from the user stack, but it only takes one from there. Signed-off-by: Albert Cahalan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/i386/kernel/vsyscall-sysenter.S b/arch/i386/kernel/vsyscall-sysenter.S index 4daefb2..76b7281 100644 --- a/arch/i386/kernel/vsyscall-sysenter.S +++ b/arch/i386/kernel/vsyscall-sysenter.S @@ -7,6 +7,21 @@ * for details. */ +/* + * The caller puts arg2 in %ecx, which gets pushed. The kernel will use + * %ecx itself for arg2. The pushing is because the sysexit instruction + * (found in entry.S) requires that we clobber %ecx with the desired %esp. + * User code might expect that %ecx is unclobbered though, as it would be + * for returning via the iret instruction, so we must push and pop. + * + * The caller puts arg3 in %edx, which the sysexit instruction requires + * for %eip. Thus, exactly as for arg2, we must push and pop. + * + * Arg6 is different. The caller puts arg6 in %ebp. Since the sysenter + * instruction clobbers %esp, the user's %esp won't even survive entry + * into the kernel. We store %esp in %ebp. Code in entry.S must fetch + * arg6 from the stack. + */ .text .globl __kernel_vsyscall .type __kernel_vsyscall,@function -- cgit v0.10.2 From e2fbf1ace5cfefdd192f29fd4a027422f567c62d Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Tue, 14 Feb 2006 13:53:21 -0800 Subject: [PATCH] x86: gitignore some autogenerated files for i386 Add some more gitignore files for i386 architecture. This files are created during the build process of a i386 kernel. Signed-off-by: Thomas Meyer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/i386/boot/.gitignore b/arch/i386/boot/.gitignore new file mode 100644 index 0000000..495f20c --- /dev/null +++ b/arch/i386/boot/.gitignore @@ -0,0 +1,3 @@ +bootsect +bzImage +setup diff --git a/arch/i386/boot/tools/.gitignore b/arch/i386/boot/tools/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/arch/i386/boot/tools/.gitignore @@ -0,0 +1 @@ +build diff --git a/arch/i386/kernel/.gitignore b/arch/i386/kernel/.gitignore new file mode 100644 index 0000000..40836ad --- /dev/null +++ b/arch/i386/kernel/.gitignore @@ -0,0 +1 @@ +vsyscall.lds -- cgit v0.10.2 From 10ee39fe3ff618d274e1cd0f6abbc2917b736bfd Mon Sep 17 00:00:00 2001 From: Christian Trefzer Date: Tue, 14 Feb 2006 13:53:26 -0800 Subject: [PATCH] neofb: avoid resetting display config on unblank Fix issues with the NeoMagic framebuffer driver. It nicely complements my previous fix already in linus' tree. The only thing missing now is that the external CRT will not be activated at neofb init when external-only is selected, either by register read or module/kernel parameter. Testing was done on a Dell Latitude CPi-A/NM2200 chip. Previous behaviour: - before booting linux, set the preferred display config X via FN+F8 - boot linux, neofb stores the register values in a private variable - change the display config to Y via keystroke - leave the machine in peace until display is blanked - touching any key will result in display config X being restored - booting up, the BIOS will acknowledge config Y, though... Current behaviour: At the time of unblanking, config Y is honoured because we now read back register contents instead of just overwriting them with outdated values. Signed-off by: Christian Trefzer Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 747602a..b85e2b1 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -1334,6 +1334,12 @@ static int neofb_blank(int blank_mode, struct fb_info *info) struct neofb_par *par = info->par; int seqflags, lcdflags, dpmsflags, reg; + /* + * Reload the value stored in the register, might have been changed via + * FN keystroke + */ + par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; + switch (blank_mode) { case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ @@ -1366,7 +1372,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info) case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ - dpmsflags = 0; /* no hsync/vsync suppression */ + dpmsflags = 0x00; /* no hsync/vsync suppression */ break; case FB_BLANK_UNBLANK: /* unblank */ seqflags = 0; /* Enable sequencer */ -- cgit v0.10.2 From 93544cc6486bea12e127ed58ca33477bb6ceafe6 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 14 Feb 2006 22:30:52 -0600 Subject: [PATCH] CIFS: fix cifs_user_read oops when null SMB response on forcedirectio mount This patch fixes an oops reported by Adrian Bunk in cifs_user_read when a null read response is returned on a forcedirectio mount. Signed-off-by: Dave Kleikamp Signed-off-by: Steve French Signed-off-by: Linus Torvalds diff --git a/fs/cifs/file.c b/fs/cifs/file.c index d17c97d..675bd25 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1442,13 +1442,15 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, &bytes_read, &smb_read_data, &buf_type); pSMBr = (struct smb_com_read_rsp *)smb_read_data; - if (copy_to_user(current_offset, - smb_read_data + 4 /* RFC1001 hdr */ - + le16_to_cpu(pSMBr->DataOffset), - bytes_read)) { - rc = -EFAULT; - } if (smb_read_data) { + if (copy_to_user(current_offset, + smb_read_data + + 4 /* RFC1001 length field */ + + le16_to_cpu(pSMBr->DataOffset), + bytes_read)) { + rc = -EFAULT; + } + if(buf_type == CIFS_SMALL_BUFFER) cifs_small_buf_release(smb_read_data); else if(buf_type == CIFS_LARGE_BUFFER) -- cgit v0.10.2 From a09d31ff762a3671f2ae41b3bca50a100c5e4da6 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Wed, 15 Feb 2006 00:48:40 -0500 Subject: Input: ixp4xx-beeper - fix compile error Signed-off-by: Alessandro Zummo Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index d448bb5..3a6ae85c 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -19,6 +19,7 @@ #include #include #include +#include #include MODULE_AUTHOR("Alessandro Zummo "); -- cgit v0.10.2 From 50f6dde0ad05ee4ee8450feb731b15b716115c4d Mon Sep 17 00:00:00 2001 From: Meelis Roos Date: Wed, 15 Feb 2006 00:48:58 -0500 Subject: Input: logips2pp - add new signature (99) Add Logitech mouse type 99 (Premium Optical Wheel Mouse, model M-BT58, plain 3 buttons + wheel) to cure the following message: logips2pp: Detected unknown logitech mouse model 99 Signed-off-by: Meelis Roos Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index c88520d..40333d6 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -232,6 +232,7 @@ static struct ps2pp_info *get_model_info(unsigned char model) { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, { 96, 0, 0 }, { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL }, + { 99, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, { 100, PS2PP_KIND_MX, /* MX510 */ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, -- cgit v0.10.2 From b8044c74bcd64bd1a9d2e8cec58fdcd40f16f5a4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 15 Feb 2006 00:49:09 -0500 Subject: Input: trackpoint - enable devices connected to external port Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index b4898d8..6d9ec9a 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -68,15 +68,19 @@ struct trackpoint_attr_data { size_t field_offset; unsigned char command; unsigned char mask; + unsigned char inverted; }; static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf) { struct trackpoint_data *tp = psmouse->private; struct trackpoint_attr_data *attr = data; - unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); + unsigned char value = *(unsigned char *)((char *)tp + attr->field_offset); + + if (attr->inverted) + value = !value; - return sprintf(buf, "%u\n", *field); + return sprintf(buf, "%u\n", value); } static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, @@ -120,6 +124,9 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, if (*rest || value > 1) return -EINVAL; + if (attr->inverted) + value = !value; + if (*field != value) { *field = value; trackpoint_toggle_bit(&psmouse->ps2dev, attr->command, attr->mask); @@ -129,11 +136,12 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, } -#define TRACKPOINT_BIT_ATTR(_name, _command, _mask) \ +#define TRACKPOINT_BIT_ATTR(_name, _command, _mask, _inv) \ static struct trackpoint_attr_data trackpoint_attr_##_name = { \ .field_offset = offsetof(struct trackpoint_data, _name), \ .command = _command, \ .mask = _mask, \ + .inverted = _inv, \ }; \ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ &trackpoint_attr_##_name, \ @@ -150,9 +158,9 @@ TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH); TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME); TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV); -TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON); -TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK); -TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV); +TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0); +TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, 0); +TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, 1); static struct attribute *trackpoint_attrs[] = { &psmouse_attr_sensitivity.dattr.attr, diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index 9857d8b..050298b 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h @@ -78,7 +78,7 @@ #define TP_TOGGLE_MB 0x23 /* Disable/Enable Middle Button */ #define TP_MASK_MB 0x01 -#define TP_TOGGLE_EXT_DEV 0x23 /* Toggle external device */ +#define TP_TOGGLE_EXT_DEV 0x23 /* Disable external device */ #define TP_MASK_EXT_DEV 0x02 #define TP_TOGGLE_DRIFT 0x23 /* Drift Correction */ #define TP_MASK_DRIFT 0x80 @@ -125,7 +125,7 @@ #define TP_DEF_MB 0x00 #define TP_DEF_PTSON 0x00 #define TP_DEF_SKIPBACK 0x00 -#define TP_DEF_EXT_DEV 0x01 +#define TP_DEF_EXT_DEV 0x00 /* 0 means enabled */ #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd)) -- cgit v0.10.2 From a90f7e98b7df3309ebc0e389076990456db20989 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 15 Feb 2006 00:49:22 -0500 Subject: Input: ads7846 - convert to to dynamic input_dev allocation Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index b45a45c..72cf0a2 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -60,7 +60,7 @@ struct ts_event { }; struct ads7846 { - struct input_dev input; + struct input_dev *input; char phys[32]; struct spi_device *spi; @@ -152,7 +152,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); int status; int sample; - int i; + int i; if (!req) return -ENOMEM; @@ -236,11 +236,12 @@ SHOW(vbatt) static void ads7846_rx(void *ads) { - struct ads7846 *ts = ads; - unsigned Rt; - unsigned sync = 0; - u16 x, y, z1, z2; - unsigned long flags; + struct ads7846 *ts = ads; + struct input_dev *input_dev = ts->input; + unsigned Rt; + unsigned sync = 0; + u16 x, y, z1, z2; + unsigned long flags; /* adjust: 12 bit samples (left aligned), built from * two 8 bit values writen msb-first. @@ -276,21 +277,21 @@ static void ads7846_rx(void *ads) * won't notice that, even if nPENIRQ never fires ... */ if (!ts->pendown && Rt != 0) { - input_report_key(&ts->input, BTN_TOUCH, 1); + input_report_key(input_dev, BTN_TOUCH, 1); sync = 1; } else if (ts->pendown && Rt == 0) { - input_report_key(&ts->input, BTN_TOUCH, 0); + input_report_key(input_dev, BTN_TOUCH, 0); sync = 1; } if (Rt) { - input_report_abs(&ts->input, ABS_X, x); - input_report_abs(&ts->input, ABS_Y, y); - input_report_abs(&ts->input, ABS_PRESSURE, Rt); + input_report_abs(input_dev, ABS_X, x); + input_report_abs(input_dev, ABS_Y, y); + input_report_abs(input_dev, ABS_PRESSURE, Rt); sync = 1; } if (sync) - input_sync(&ts->input); + input_sync(input_dev); #ifdef VERBOSE if (Rt || ts->pendown) @@ -396,9 +397,11 @@ static int ads7846_resume(struct spi_device *spi) static int __devinit ads7846_probe(struct spi_device *spi) { struct ads7846 *ts; + struct input_dev *input_dev; struct ads7846_platform_data *pdata = spi->dev.platform_data; struct spi_transfer *x; int i; + int err; if (!spi->irq) { dev_dbg(&spi->dev, "no IRQ?\n"); @@ -423,13 +426,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) * to discard the four garbage LSBs. */ - if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL))) - return -ENOMEM; + ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ts || !input_dev) { + err = -ENOMEM; + goto err_free_mem; + } dev_set_drvdata(&spi->dev, ts); + spi->dev.power.power_state = PMSG_ON; ts->spi = spi; - spi->dev.power.power_state = PMSG_ON; + ts->input = input_dev; init_timer(&ts->timer); ts->timer.data = (unsigned long) ts; @@ -439,28 +447,25 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; - init_input_dev(&ts->input); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); - ts->input.dev = &spi->dev; - ts->input.name = "ADS784x Touchscreen"; - snprintf(ts->phys, sizeof ts->phys, "%s/input0", spi->dev.bus_id); - ts->input.phys = ts->phys; + input_dev->name = "ADS784x Touchscreen"; + input_dev->phys = ts->phys; + input_dev->cdev.dev = &spi->dev; - ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(&ts->input, ABS_X, + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, pdata->x_min ? : 0, pdata->x_max ? : MAX_12BIT, 0, 0); - input_set_abs_params(&ts->input, ABS_Y, + input_set_abs_params(input_dev, ABS_Y, pdata->y_min ? : 0, pdata->y_max ? : MAX_12BIT, 0, 0); - input_set_abs_params(&ts->input, ABS_PRESSURE, + input_set_abs_params(input_dev, ABS_PRESSURE, pdata->pressure_min, pdata->pressure_max, 0, 0); - input_register_device(&ts->input); - /* set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ @@ -510,9 +515,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, spi->dev.bus_id, ts)) { dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); - input_unregister_device(&ts->input); - kfree(ts); - return -EBUSY; + err = -EBUSY; + goto err_free_mem; } dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); @@ -534,7 +538,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) device_create_file(&spi->dev, &dev_attr_vbatt); device_create_file(&spi->dev, &dev_attr_vaux); + err = input_register_device(input_dev); + if (err) + goto err_free_irq; + return 0; + + err_free_irq: + free_irq(spi->irq, ts); + err_free_mem: + input_free_device(input_dev); + kfree(ts); + return err; } static int __devexit ads7846_remove(struct spi_device *spi) @@ -554,7 +569,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) device_remove_file(&spi->dev, &dev_attr_vbatt); device_remove_file(&spi->dev, &dev_attr_vaux); - input_unregister_device(&ts->input); + input_unregister_device(ts->input); kfree(ts); dev_dbg(&spi->dev, "unregistered touchscreen\n"); -- cgit v0.10.2 From d93f70b2d758e79ee4ac9d6d982e3f532453911f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 15 Feb 2006 00:49:35 -0500 Subject: Input: ads7846 - assorted updates This updates the ads7846 touchscreen driver: - to allow faster clocking (this driver doesn't push sample rates); - bugfixes the conversion of spi_transfer to lists; - some dma-unsafe command buffers are fixed. Signed-off-by: David Brownell Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 72cf0a2..8c12a97 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -48,10 +48,13 @@ #define TS_POLL_PERIOD msecs_to_jiffies(10) +/* this driver doesn't aim at the peak continuous sample rate */ +#define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) + struct ts_event { /* For portability, we can't read 12 bit values using SPI (which * would make the controller deliver them as native byteorder u16 - * with msbs zeroed). Instead, we read them as two 8-byte values, + * with msbs zeroed). Instead, we read them as two 8-bit values, * which need byteswapping then range adjustment. */ __be16 x; @@ -68,6 +71,7 @@ struct ads7846 { u16 vref_delay_usecs; u16 x_plate_ohms; + u8 read_x, read_y, read_z1, read_z2; struct ts_event tc; struct spi_transfer xfer[8]; @@ -117,10 +121,10 @@ struct ads7846 { #define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \ | ADS_12_BIT | ADS_DFR) -static const u8 read_y = READ_12BIT_DFR(y) | ADS_PD10_ADC_ON; -static const u8 read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON; -static const u8 read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON; -static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */ +#define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) +#define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) +#define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) +#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_PDOWN) /* LAST */ /* single-ended samples need to first power up reference voltage; * we leave both ADC and VREF powered @@ -128,8 +132,8 @@ static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */ #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ | ADS_12_BIT | ADS_SER) -static const u8 ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON; -static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN; +#define REF_ON (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON) +#define REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /*--------------------------------------------------------------------------*/ @@ -138,7 +142,9 @@ static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN; */ struct ser_req { + u8 ref_on; u8 command; + u8 ref_off; u16 scratch; __be16 sample; struct spi_message msg; @@ -160,7 +166,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) INIT_LIST_HEAD(&req->msg.transfers); /* activate reference, so it has time to settle; */ - req->xfer[0].tx_buf = &ref_on; + req->ref_on = REF_ON; + req->xfer[0].tx_buf = &req->ref_on; req->xfer[0].len = 1; req->xfer[1].rx_buf = &req->scratch; req->xfer[1].len = 2; @@ -182,7 +189,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) /* REVISIT: take a few more samples, and compare ... */ /* turn off reference */ - req->xfer[4].tx_buf = &ref_off; + req->ref_off = REF_OFF; + req->xfer[4].tx_buf = &req->ref_off; req->xfer[4].len = 1; req->xfer[5].rx_buf = &req->scratch; req->xfer[5].len = 2; @@ -400,7 +408,6 @@ static int __devinit ads7846_probe(struct spi_device *spi) struct input_dev *input_dev; struct ads7846_platform_data *pdata = spi->dev.platform_data; struct spi_transfer *x; - int i; int err; if (!spi->irq) { @@ -414,9 +421,9 @@ static int __devinit ads7846_probe(struct spi_device *spi) } /* don't exceed max specified sample rate */ - if (spi->max_speed_hz > (125000 * 16)) { + if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { dev_dbg(&spi->dev, "f(sample) %d KHz?\n", - (spi->max_speed_hz/16)/1000); + (spi->max_speed_hz/SAMPLE_BITS)/1000); return -EINVAL; } @@ -469,45 +476,58 @@ static int __devinit ads7846_probe(struct spi_device *spi) /* set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ + INIT_LIST_HEAD(&ts->msg.transfers); x = ts->xfer; /* y- still on; turn on only y+ (and ADC) */ - x->tx_buf = &read_y; + ts->read_y = READ_Y; + x->tx_buf = &ts->read_y; x->len = 1; + spi_message_add_tail(x, &ts->msg); + x++; x->rx_buf = &ts->tc.y; x->len = 2; - x++; + spi_message_add_tail(x, &ts->msg); /* turn y+ off, x- on; we'll use formula #2 */ if (ts->model == 7846) { - x->tx_buf = &read_z1; + x++; + ts->read_z1 = READ_Z1; + x->tx_buf = &ts->read_z1; x->len = 1; + spi_message_add_tail(x, &ts->msg); + x++; x->rx_buf = &ts->tc.z1; x->len = 2; - x++; + spi_message_add_tail(x, &ts->msg); - x->tx_buf = &read_z2; + x++; + ts->read_z2 = READ_Z2; + x->tx_buf = &ts->read_z2; x->len = 1; + spi_message_add_tail(x, &ts->msg); + x++; x->rx_buf = &ts->tc.z2; x->len = 2; - x++; + spi_message_add_tail(x, &ts->msg); } /* turn y- off, x+ on, then leave in lowpower */ - x->tx_buf = &read_x; + x++; + ts->read_x = READ_X; + x->tx_buf = &ts->read_x; x->len = 1; + spi_message_add_tail(x, &ts->msg); + x++; x->rx_buf = &ts->tc.x; x->len = 2; - x++; - - CS_CHANGE(x[-1]); + CS_CHANGE(*x); + spi_message_add_tail(x, &ts->msg); - for (i = 0; i < x - ts->xfer; i++) - spi_message_add_tail(&ts->xfer[i], &ts->msg); ts->msg.complete = ads7846_rx; ts->msg.context = ts; -- cgit v0.10.2 From 02860ab6cd2c71dbe42fa70a65a97823c213635b Mon Sep 17 00:00:00 2001 From: Arthur Othieno Date: Wed, 15 Feb 2006 00:49:48 -0500 Subject: Input: kill remnants of 98kbd{,-io} and 98spkr 98kbd{,-io} and 98spkr all went out with PC98 subarch. Remove stale Makefile entries that remained. Signed-off-by: Arthur Othieno Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 6e0afbb..2708167 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o -obj-$(CONFIG_KEYBOARD_98KBD) += 98kbd.o obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 184c412..415c491 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o -obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 678a859..4155197 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o -obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o obj-$(CONFIG_HP_SDC) += hp_sdc.o obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o -- cgit v0.10.2 From ee68cea2c26b7a8222f9020f54d22c6067011e8b Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 15 Feb 2006 01:34:23 -0800 Subject: [NETFILTER]: Fix xfrm lookup after SNAT To find out if a packet needs to be handled by IPsec after SNAT, packets are currently rerouted in POST_ROUTING and a new xfrm lookup is done. This breaks SNAT of non-unicast packets to non-local addresses because the packet is routed as incoming packet and no neighbour entry is bound to the dst_entry. In general, it seems to be a bad idea to replace the dst_entry after the packet was already sent to the output routine because its state might not match what's expected. This patch changes the xfrm lookup in POST_ROUTING to re-use the original dst_entry without routing the packet again. This means no policy routing can be used for transport mode transforms (which keep the original route) when packets are SNATed to match the policy, but it looks like the best we can do for now. Signed-off-by: Patrick McHardy Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h index fdc4a95..43c09d7 100644 --- a/include/linux/netfilter_ipv4.h +++ b/include/linux/netfilter_ipv4.h @@ -79,7 +79,7 @@ enum nf_ip_hook_priorities { #ifdef __KERNEL__ extern int ip_route_me_harder(struct sk_buff **pskb); - +extern int ip_xfrm_me_harder(struct sk_buff **pskb); #endif /*__KERNEL__*/ #endif /*__LINUX_IP_NETFILTER_H*/ diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 52a3d7c..ed42cdc 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -78,6 +78,47 @@ int ip_route_me_harder(struct sk_buff **pskb) } EXPORT_SYMBOL(ip_route_me_harder); +#ifdef CONFIG_XFRM +int ip_xfrm_me_harder(struct sk_buff **pskb) +{ + struct flowi fl; + unsigned int hh_len; + struct dst_entry *dst; + + if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) + return 0; + if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0) + return -1; + + dst = (*pskb)->dst; + if (dst->xfrm) + dst = ((struct xfrm_dst *)dst)->route; + dst_hold(dst); + + if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0) + return -1; + + dst_release((*pskb)->dst); + (*pskb)->dst = dst; + + /* Change in oif may mean change in hh_len. */ + hh_len = (*pskb)->dst->dev->hard_header_len; + if (skb_headroom(*pskb) < hh_len) { + struct sk_buff *nskb; + + nskb = skb_realloc_headroom(*pskb, hh_len); + if (!nskb) + return -1; + if ((*pskb)->sk) + skb_set_owner_w(nskb, (*pskb)->sk); + kfree_skb(*pskb); + *pskb = nskb; + } + return 0; +} +EXPORT_SYMBOL(ip_xfrm_me_harder); +#endif + void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); EXPORT_SYMBOL(ip_nat_decode_session); diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 92c5499..7c3f7d3 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -235,19 +235,19 @@ ip_nat_out(unsigned int hooknum, return NF_ACCEPT; ret = ip_nat_fn(hooknum, pskb, in, out, okfn); +#ifdef CONFIG_XFRM if (ret != NF_DROP && ret != NF_STOLEN && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); if (ct->tuplehash[dir].tuple.src.ip != ct->tuplehash[!dir].tuple.dst.ip -#ifdef CONFIG_XFRM || ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all -#endif ) - return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; + return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP; } +#endif return ret; } -- cgit v0.10.2 From 78872ccb68335b14f0d1ac7338ecfcbf1cba1df4 Mon Sep 17 00:00:00 2001 From: Adrian Drzewiecki Date: Wed, 15 Feb 2006 01:47:48 -0800 Subject: [BRIDGE]: Fix deadlock in br_stp_disable_bridge Looks like somebody forgot to use the _bh spin_lock variant. We ran into a deadlock where br->hello_timer expired while br_stp_disable_br() walked br->port_list. Signed-off-by: Adrian Drzewiecki Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index cc047f7..35cf3a0 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -67,7 +67,7 @@ void br_stp_disable_bridge(struct net_bridge *br) { struct net_bridge_port *p; - spin_lock(&br->lock); + spin_lock_bh(&br->lock); list_for_each_entry(p, &br->port_list, list) { if (p->state != BR_STATE_DISABLED) br_stp_disable_port(p); @@ -76,7 +76,7 @@ void br_stp_disable_bridge(struct net_bridge *br) br->topology_change = 0; br->topology_change_detected = 0; - spin_unlock(&br->lock); + spin_unlock_bh(&br->lock); del_timer_sync(&br->hello_timer); del_timer_sync(&br->topology_change_timer); -- cgit v0.10.2 From a5f1e4edb3cdd90733893b8aec38fac5553db60a Mon Sep 17 00:00:00 2001 From: Arthur Othieno Date: Wed, 15 Feb 2006 09:52:46 +0000 Subject: [SERIAL] Documentation/jsm.txt is a no show. In kernel bugzilla #5176 (http://bugzilla.kernel.org/show_bug.cgi?id=5176) Harry R\374ter points out Documentation/jsm.txt is missing. No one at Digi seems to care, so just remove the stale reference. Signed-off-by: Arthur Othieno Signed-off-by: Russell King diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 0f4361c..b3c561a 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -902,8 +902,8 @@ config SERIAL_JSM something like this to connect more than two modems to your Linux box, for instance in order to become a dial-in server. This driver supports PCI boards only. - If you have a card like this, say Y here and read the file - . + + If you have a card like this, say Y here, otherwise say N. To compile this driver as a module, choose M here: the module will be called jsm. -- cgit v0.10.2 From dc7bf130b8552a218e2f3ea0b58268e469f335da Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 15 Feb 2006 09:59:47 +0000 Subject: [SERIAL] Fix typo in comment Signed-off-by: Ralf Baechle Signed-off-by: Russell King diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index b1fc97d..244e8ff 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2198,7 +2198,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) touch_nmi_watchdog(); /* - * First save the UER then disable the interrupts + * First save the IER then disable the interrupts */ ier = serial_in(up, UART_IER); -- cgit v0.10.2 From ba09cf2bcf9b74d852dcb5ea957ac6af2bc0e057 Mon Sep 17 00:00:00 2001 From: Herbert Poetzl Date: Wed, 15 Feb 2006 10:13:02 +0000 Subject: [ARM] remove duplicate #includes Signed-off-by: Herbert P?tzl Signed-off-by: Russell King diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c index e4f4c52..0ebbcb2 100644 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ b/arch/arm/mach-iop3xx/iop321-setup.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index 6358548..2d6abe5 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c index 1a24e2c..093efd7 100644 --- a/arch/arm/plat-omap/pm.c +++ b/arch/arm/plat-omap/pm.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index d574dd3..9451932 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -82,7 +82,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 3f17da699431ec48540beabc55c54d4b5e66c8e7 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 15 Feb 2006 22:13:24 +0300 Subject: [PATCH] fix kill_proc_info() vs CLONE_THREAD race There is a window after copy_process() unlocks ->sighand.siglock and before it adds the new thread to the thread list. In that window __group_complete_signal(SIGKILL) will not see the new thread yet, so this thread will start running while the whole thread group was supposed to exit. I beleive we have another good reason to place attach_pid(PID/TGID) under ->sighand.siglock. We can do the same for release_task()->__unhash_process() de_thread()->switch_exec_pids() After that we don't need tasklist_lock to iterate over the thread list, and we can simplify things, see for example do_sigaction() or sys_times(). Signed-off-by: Oleg Nesterov Cc: Roland McGrath Cc: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/kernel/fork.c b/kernel/fork.c index 8e88b37..3683ce1 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1123,8 +1123,8 @@ static task_t *copy_process(unsigned long clone_flags, p->real_parent = current; p->parent = p->real_parent; + spin_lock(¤t->sighand->siglock); if (clone_flags & CLONE_THREAD) { - spin_lock(¤t->sighand->siglock); /* * Important: if an exit-all has been started then * do not create this new thread - the whole thread @@ -1162,8 +1162,6 @@ static task_t *copy_process(unsigned long clone_flags, */ p->it_prof_expires = jiffies_to_cputime(1); } - - spin_unlock(¤t->sighand->siglock); } /* @@ -1189,6 +1187,7 @@ static task_t *copy_process(unsigned long clone_flags, nr_threads++; total_forks++; + spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); proc_fork_connector(p); return p; -- cgit v0.10.2 From dadac81b1b86196fcc48fb87620403c4a7174f06 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 15 Feb 2006 22:13:26 +0300 Subject: [PATCH] fix kill_proc_info() vs fork() theoretical race copy_process: attach_pid(p, PIDTYPE_PID, p->pid); attach_pid(p, PIDTYPE_TGID, p->tgid); What if kill_proc_info(p->pid) happens in between? copy_process() holds current->sighand.siglock, so we are safe in CLONE_THREAD case, because current->sighand == p->sighand. Otherwise, p->sighand is unlocked, the new process is already visible to the find_task_by_pid(), but have a copy of parent's 'struct pid' in ->pids[PIDTYPE_TGID]. This means that __group_complete_signal() may hang while doing do ... while (next_thread() != p) We can solve this problem if we reverse these 2 attach_pid()s: attach_pid() does wmb() group_send_sig_info() calls spin_lock(), which provides a read barrier. // Yes ? I don't think we can hit this race in practice, but still. Signed-off-by: Oleg Nesterov Cc: Roland McGrath Cc: Ingo Molnar Signed-off-by: Linus Torvalds diff --git a/kernel/fork.c b/kernel/fork.c index 3683ce1..fbea12d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1173,8 +1173,6 @@ static task_t *copy_process(unsigned long clone_flags, if (unlikely(p->ptrace & PT_PTRACED)) __ptrace_link(p, current->parent); - attach_pid(p, PIDTYPE_PID, p->pid); - attach_pid(p, PIDTYPE_TGID, p->tgid); if (thread_group_leader(p)) { p->signal->tty = current->signal->tty; p->signal->pgrp = process_group(current); @@ -1184,6 +1182,8 @@ static task_t *copy_process(unsigned long clone_flags, if (p->pid) __get_cpu_var(process_counts)++; } + attach_pid(p, PIDTYPE_TGID, p->tgid); + attach_pid(p, PIDTYPE_PID, p->pid); nr_threads++; total_forks++; -- cgit v0.10.2 From 5ecfbae093f0c37311e89b29bfc0c9d586eace87 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 15 Feb 2006 22:50:10 +0300 Subject: [PATCH] fix zap_thread's ptrace related problems 1. The tracee can go from ptrace_stop() to do_signal_stop() after __ptrace_unlink(p). 2. It is unsafe to __ptrace_unlink(p) while p->parent may wait for tasklist_lock in ptrace_detach(). Signed-off-by: Oleg Nesterov Cc: Roland McGrath Cc: Ingo Molnar Cc: Christoph Hellwig Cc: Eric W. Biederman Signed-off-by: Linus Torvalds diff --git a/fs/exec.c b/fs/exec.c index 055378d..0e1c950 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1403,7 +1403,7 @@ static void zap_threads (struct mm_struct *mm) do_each_thread(g,p) { if (mm == p->mm && p != tsk && p->ptrace && p->parent->mm == mm) { - __ptrace_unlink(p); + __ptrace_detach(p, 0); } } while_each_thread(g,p); write_unlock_irq(&tasklist_lock); diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 9d5cd10..0d36750 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -84,6 +84,7 @@ extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __us extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); extern int ptrace_attach(struct task_struct *tsk); extern int ptrace_detach(struct task_struct *, unsigned int); +extern void __ptrace_detach(struct task_struct *, unsigned int); extern void ptrace_disable(struct task_struct *); extern int ptrace_check_attach(struct task_struct *task, int kill); extern int ptrace_request(struct task_struct *child, long request, long addr, long data); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index d2cf144..d95a72c 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -72,8 +72,8 @@ void ptrace_untrace(task_t *child) */ void __ptrace_unlink(task_t *child) { - if (!child->ptrace) - BUG(); + BUG_ON(!child->ptrace); + child->ptrace = 0; if (!list_empty(&child->ptrace_list)) { list_del_init(&child->ptrace_list); @@ -184,22 +184,27 @@ bad: return retval; } +void __ptrace_detach(struct task_struct *child, unsigned int data) +{ + child->exit_code = data; + /* .. re-parent .. */ + __ptrace_unlink(child); + /* .. and wake it up. */ + if (child->exit_state != EXIT_ZOMBIE) + wake_up_process(child); +} + int ptrace_detach(struct task_struct *child, unsigned int data) { if (!valid_signal(data)) - return -EIO; + return -EIO; /* Architecture-specific hardware disable .. */ ptrace_disable(child); - /* .. re-parent .. */ - child->exit_code = data; - write_lock_irq(&tasklist_lock); - __ptrace_unlink(child); - /* .. and wake it up. */ - if (child->exit_state != EXIT_ZOMBIE) - wake_up_process(child); + if (child->ptrace) + __ptrace_detach(child, data); write_unlock_irq(&tasklist_lock); return 0; -- cgit v0.10.2 From 50d8e59038703c4da5acaed9afaa37ae416d3153 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sun, 12 Feb 2006 17:01:35 +0100 Subject: [IA64] Remove duplicate EXPORT_SYMBOLs Remove symbol exports from ia64_ksyms.c that are already exported in lib/string.c. Signed-off-by: Andreas Schwab Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index e72de58..bbcfd08 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -10,23 +10,8 @@ #include EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memchr); -EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(memscan); -EXPORT_SYMBOL(strcat); -EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strncat); -EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(strncpy); -EXPORT_SYMBOL(strnlen); -EXPORT_SYMBOL(strrchr); -EXPORT_SYMBOL(strstr); -EXPORT_SYMBOL(strpbrk); #include EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */ -- cgit v0.10.2 From 8ed9b2c7a804335004e4bd3b4c6989c5b6bc243f Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 13 Feb 2006 05:29:57 -0500 Subject: [IA64-SGI] sn2 minor fixes and cleanups General SN2 code cleanup: - Do not initialize global variables to zero - Use kzalloc instead of kmalloc+memset - Check kmalloc return values - Do not obfuscate spin lock calls - Remove some unused code - Various formatting cleanups Signed-off-by: Jes Sorensen Signed-off-by: Tony Luck diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 3437c23..dfb3f29 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -23,6 +23,10 @@ #include "xtalk/hubdev.h" #include "xtalk/xwidgetdev.h" + +extern void sn_init_cpei_timer(void); +extern void register_sn_procfs(void); + static struct list_head sn_sysdata_list; /* sysdata list struct */ @@ -40,12 +44,12 @@ struct brick { struct slab_info slab_info[MAX_SLABS + 1]; }; -int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */ +int sn_ioif_inited; /* SN I/O infrastructure initialized? */ struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ -static int max_segment_number = 0; /* Default highest segment number */ -static int max_pcibus_number = 255; /* Default highest pci bus number */ +static int max_segment_number; /* Default highest segment number */ +static int max_pcibus_number = 255; /* Default highest pci bus number */ /* * Hooks and struct for unsupported pci providers @@ -84,7 +88,6 @@ static inline u64 sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, u64 address) { - struct ia64_sal_retval ret_stuff; ret_stuff.status = 0; ret_stuff.v0 = 0; @@ -94,7 +97,6 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, (u64) nasid, (u64) widget_num, (u64) device_num, (u64) address, 0, 0, 0); return ret_stuff.status; - } /* @@ -102,7 +104,6 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, */ static inline u64 sal_get_hubdev_info(u64 handle, u64 address) { - struct ia64_sal_retval ret_stuff; ret_stuff.status = 0; ret_stuff.v0 = 0; @@ -118,7 +119,6 @@ static inline u64 sal_get_hubdev_info(u64 handle, u64 address) */ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) { - struct ia64_sal_retval ret_stuff; ret_stuff.status = 0; ret_stuff.v0 = 0; @@ -215,7 +215,7 @@ static void __init sn_fixup_ionodes(void) struct hubdev_info *hubdev; u64 status; u64 nasid; - int i, widget, device; + int i, widget, device, size; /* * Get SGI Specific HUB chipset information. @@ -251,48 +251,37 @@ static void __init sn_fixup_ionodes(void) if (!hubdev->hdi_flush_nasid_list.widget_p) continue; + size = (HUB_WIDGET_ID_MAX + 1) * + sizeof(struct sn_flush_device_kernel *); hubdev->hdi_flush_nasid_list.widget_p = - kmalloc((HUB_WIDGET_ID_MAX + 1) * - sizeof(struct sn_flush_device_kernel *), - GFP_KERNEL); - memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0, - (HUB_WIDGET_ID_MAX + 1) * - sizeof(struct sn_flush_device_kernel *)); + kzalloc(size, GFP_KERNEL); + if (!hubdev->hdi_flush_nasid_list.widget_p) + BUG(); for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { - sn_flush_device_kernel = kmalloc(DEV_PER_WIDGET * - sizeof(struct - sn_flush_device_kernel), - GFP_KERNEL); + size = DEV_PER_WIDGET * + sizeof(struct sn_flush_device_kernel); + sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); if (!sn_flush_device_kernel) BUG(); - memset(sn_flush_device_kernel, 0x0, - DEV_PER_WIDGET * - sizeof(struct sn_flush_device_kernel)); dev_entry = sn_flush_device_kernel; for (device = 0; device < DEV_PER_WIDGET; device++,dev_entry++) { - dev_entry->common = kmalloc(sizeof(struct - sn_flush_device_common), - GFP_KERNEL); + size = sizeof(struct sn_flush_device_common); + dev_entry->common = kzalloc(size, GFP_KERNEL); if (!dev_entry->common) BUG(); - memset(dev_entry->common, 0x0, sizeof(struct - sn_flush_device_common)); if (sn_prom_feature_available( PRF_DEVICE_FLUSH_LIST)) status = sal_get_device_dmaflush_list( - nasid, - widget, - device, - (u64)(dev_entry->common)); + nasid, widget, device, + (u64)(dev_entry->common)); else status = sn_device_fixup_war(nasid, - widget, - device, - dev_entry->common); + widget, device, + dev_entry->common); if (status != SALRET_OK) panic("SAL call failed: %s\n", ia64_sal_strerror(status)); @@ -383,13 +372,12 @@ void sn_pci_fixup_slot(struct pci_dev *dev) pci_dev_get(dev); /* for the sysdata pointer */ pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (pcidev_info <= 0) + if (!pcidev_info) BUG(); /* Cannot afford to run out of memory */ - sn_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (sn_irq_info <= 0) + sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); + if (!sn_irq_info) BUG(); /* Cannot afford to run out of memory */ - memset(sn_irq_info, 0, sizeof(struct sn_irq_info)); /* Call to retrieve pci device information needed by kernel. */ status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, @@ -482,13 +470,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev) */ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) { - int status = 0; + int status; int nasid, cnode; struct pci_controller *controller; struct sn_pci_controller *sn_controller; struct pcibus_bussoft *prom_bussoft_ptr; struct hubdev_info *hubdev_info; - void *provider_soft = NULL; + void *provider_soft; struct sn_pcibus_provider *provider; status = sal_get_pcibus_info((u64) segment, (u64) busnum, @@ -535,6 +523,8 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) bus->sysdata = controller; if (provider->bus_fixup) provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); + else + provider_soft = NULL; if (provider_soft == NULL) { /* fixup failed or not applicable */ @@ -638,13 +628,8 @@ void sn_bus_free_sysdata(void) static int __init sn_pci_init(void) { - int i = 0; - int j = 0; + int i, j; struct pci_dev *pci_dev = NULL; - extern void sn_init_cpei_timer(void); -#ifdef CONFIG_PROC_FS - extern void register_sn_procfs(void); -#endif if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; @@ -700,32 +685,29 @@ static int __init sn_pci_init(void) */ void hubdev_init_node(nodepda_t * npda, cnodeid_t node) { - struct hubdev_info *hubdev_info; + int size; + pg_data_t *pg; + + size = sizeof(struct hubdev_info); if (node >= num_online_nodes()) /* Headless/memless IO nodes */ - hubdev_info = - (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(0), - sizeof(struct - hubdev_info)); + pg = NODE_DATA(0); else - hubdev_info = - (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(node), - sizeof(struct - hubdev_info)); - npda->pdinfo = (void *)hubdev_info; + pg = NODE_DATA(node); + hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); + + npda->pdinfo = (void *)hubdev_info; } geoid_t cnodeid_get_geoid(cnodeid_t cnode) { - struct hubdev_info *hubdev; hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); return hubdev->hdi_geoid; - } subsys_initcall(sn_pci_init); diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c index 81c63b2..6ae276d 100644 --- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c +++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1999,2001-2004, 2006 Silicon Graphics, Inc. All Rights Reserved. * * Module to export the system's Firmware Interface Tables, including * PROM revision numbers and banners, in /proc @@ -190,7 +190,7 @@ static int read_version_entry(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len = 0; + int len; /* data holds the NASID of the node */ len = dump_version(page, (unsigned long)data); @@ -202,7 +202,7 @@ static int read_fit_entry(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len = 0; + int len; /* data holds the NASID of the node */ len = dump_fit(page, (unsigned long)data); @@ -229,13 +229,16 @@ int __init prominfo_init(void) struct proc_dir_entry *p; cnodeid_t cnodeid; unsigned long nasid; + int size; char name[NODE_NAME_LEN]; if (!ia64_platform_is("sn2")) return 0; - proc_entries = kmalloc(num_online_nodes() * sizeof(struct proc_dir_entry *), - GFP_KERNEL); + size = num_online_nodes() * sizeof(struct proc_dir_entry *); + proc_entries = kzalloc(size, GFP_KERNEL); + if (!proc_entries) + return -ENOMEM; sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL); @@ -244,14 +247,12 @@ int __init prominfo_init(void) sprintf(name, "node%d", cnodeid); *entp = proc_mkdir(name, sgi_prominfo_entry); nasid = cnodeid_to_nasid(cnodeid); - p = create_proc_read_entry( - "fit", 0, *entp, read_fit_entry, - (void *)nasid); + p = create_proc_read_entry("fit", 0, *entp, read_fit_entry, + (void *)nasid); if (p) p->owner = THIS_MODULE; - p = create_proc_read_entry( - "version", 0, *entp, read_version_entry, - (void *)nasid); + p = create_proc_read_entry("version", 0, *entp, + read_version_entry, (void *)nasid); if (p) p->owner = THIS_MODULE; entp++; @@ -263,7 +264,7 @@ int __init prominfo_init(void) void __exit prominfo_exit(void) { struct proc_dir_entry **entp; - unsigned cnodeid; + unsigned int cnodeid; char name[NODE_NAME_LEN]; entp = proc_entries; diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index f153a4c..24eefb2 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -46,8 +46,14 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats); static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); -void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long, - volatile unsigned long *, unsigned long); +extern unsigned long +sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long); +void +sn2_ptc_deadlock_recovery(short *, short, short, int, + volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long); /* * Note: some is the following is captured here to make degugging easier @@ -59,16 +65,6 @@ void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned lon #define reset_max_active_on_deadlock() 1 #define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock) -static inline void ptc_lock(int sh1, unsigned long *flagp) -{ - spin_lock_irqsave(PTC_LOCK(sh1), *flagp); -} - -static inline void ptc_unlock(int sh1, unsigned long flags) -{ - spin_unlock_irqrestore(PTC_LOCK(sh1), flags); -} - struct ptc_stats { unsigned long ptc_l; unsigned long change_rid; @@ -82,6 +78,8 @@ struct ptc_stats { unsigned long shub_ptc_flushes_not_my_mm; }; +#define sn2_ptctest 0 + static inline unsigned long wait_piowc(void) { volatile unsigned long *piows; @@ -200,7 +198,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, max_active = max_active_pio(shub1); itc = ia64_get_itc(); - ptc_lock(shub1, &flags); + spin_lock_irqsave(PTC_LOCK(shub1), flags); itc2 = ia64_get_itc(); __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; @@ -258,7 +256,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, ia64_srlz_d(); } - ptc_unlock(shub1, flags); + spin_unlock_irqrestore(PTC_LOCK(shub1), flags); preempt_enable(); } @@ -270,11 +268,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, * TLB flush transaction. The recovery sequence is somewhat tricky & is * coded in assembly language. */ -void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0, - volatile unsigned long *ptc1, unsigned long data1) + +void +sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, + volatile unsigned long *ptc0, unsigned long data0, + volatile unsigned long *ptc1, unsigned long data1) { - extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, - volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long); short nasid, i; unsigned long *piows, zeroval, n; diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c index a06719d..c686d9c 100644 --- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c +++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c @@ -6,11 +6,11 @@ * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. */ #include -#include #ifdef CONFIG_PROC_FS #include #include +#include #include static int partition_id_show(struct seq_file *s, void *p) @@ -90,10 +90,10 @@ static int coherence_id_open(struct inode *inode, struct file *file) return single_open(file, coherence_id_show, NULL); } -static struct proc_dir_entry *sn_procfs_create_entry( - const char *name, struct proc_dir_entry *parent, - int (*openfunc)(struct inode *, struct file *), - int (*releasefunc)(struct inode *, struct file *)) +static struct proc_dir_entry +*sn_procfs_create_entry(const char *name, struct proc_dir_entry *parent, + int (*openfunc)(struct inode *, struct file *), + int (*releasefunc)(struct inode *, struct file *)) { struct proc_dir_entry *e = create_proc_entry(name, 0444, parent); @@ -126,24 +126,24 @@ void register_sn_procfs(void) return; sn_procfs_create_entry("partition_id", sgi_proc_dir, - partition_id_open, single_release); + partition_id_open, single_release); sn_procfs_create_entry("system_serial_number", sgi_proc_dir, - system_serial_number_open, single_release); + system_serial_number_open, single_release); sn_procfs_create_entry("licenseID", sgi_proc_dir, - licenseID_open, single_release); + licenseID_open, single_release); e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir, - sn_force_interrupt_open, single_release); + sn_force_interrupt_open, single_release); if (e) e->proc_fops->write = sn_force_interrupt_write_proc; sn_procfs_create_entry("coherence_id", sgi_proc_dir, - coherence_id_open, single_release); + coherence_id_open, single_release); sn_procfs_create_entry("sn_topology", sgi_proc_dir, - sn_topology_open, sn_topology_release); + sn_topology_open, sn_topology_release); } #endif /* CONFIG_PROC_FS */ diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index d263d3e..8a56f8b 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -284,12 +284,10 @@ struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq, if ((nasid & 1) == 0) return NULL; - sn_irq_info = kmalloc(sn_irq_size, GFP_KERNEL); + sn_irq_info = kzalloc(sn_irq_size, GFP_KERNEL); if (sn_irq_info == NULL) return NULL; - memset(sn_irq_info, 0x0, sn_irq_size); - status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq, req_nasid, slice); if (status) { diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 5a36292..b4b84c2 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -335,10 +335,10 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, - pci_domain_nr(bus), bus->number, - 0, /* io */ - 0, /* read */ - port, size, __pa(val)); + pci_domain_nr(bus), bus->number, + 0, /* io */ + 0, /* read */ + port, size, __pa(val)); if (isrv.status == 0) return size; @@ -381,10 +381,10 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, - pci_domain_nr(bus), bus->number, - 0, /* io */ - 1, /* write */ - port, size, __pa(&val)); + pci_domain_nr(bus), bus->number, + 0, /* io */ + 1, /* write */ + port, size, __pa(&val)); if (isrv.status == 0) return size; diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c index aa3fa51..1f0253b 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved. */ #include @@ -12,7 +12,7 @@ #include #include -int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ +int pcibr_invalidate_ate; /* by default don't invalidate ATE on free */ /* * mark_ate: Mark the ate as either free or inuse. @@ -20,14 +20,12 @@ int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ static void mark_ate(struct ate_resource *ate_resource, int start, int number, u64 value) { - u64 *ate = ate_resource->ate; int index; int length = 0; for (index = start; length < number; index++, length++) ate[index] = value; - } /* @@ -37,7 +35,6 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number, static int find_free_ate(struct ate_resource *ate_resource, int start, int count) { - u64 *ate = ate_resource->ate; int index; int start_free; @@ -70,12 +67,10 @@ static int find_free_ate(struct ate_resource *ate_resource, int start, static inline void free_ate_resource(struct ate_resource *ate_resource, int start) { - mark_ate(ate_resource, start, ate_resource->ate[start], 0); if ((ate_resource->lowest_free_index > start) || (ate_resource->lowest_free_index < 0)) ate_resource->lowest_free_index = start; - } /* @@ -84,7 +79,6 @@ static inline void free_ate_resource(struct ate_resource *ate_resource, static inline int alloc_ate_resource(struct ate_resource *ate_resource, int ate_needed) { - int start_index; /* @@ -118,19 +112,12 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, */ int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) { - int status = 0; - u64 flag; + int status; + unsigned long flags; - flag = pcibr_lock(pcibus_info); + spin_lock_irqsave(&pcibus_info->pbi_lock, flags); status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); - - if (status < 0) { - /* Failed to allocate */ - pcibr_unlock(pcibus_info, flag); - return -1; - } - - pcibr_unlock(pcibus_info, flag); + spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags); return status; } @@ -182,7 +169,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) ate_write(pcibus_info, index, count, (ate & ~PCI32_ATE_V)); } - flags = pcibr_lock(pcibus_info); + spin_lock_irqsave(&pcibus_info->pbi_lock, flags); free_ate_resource(&pcibus_info->pbi_int_ate_resource, index); - pcibr_unlock(pcibus_info, flags); + spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags); } diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 54ce5b7..9f86bb6 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -137,14 +137,12 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, pci_addr |= PCI64_ATTR_VIRTUAL; return pci_addr; - } static dma_addr_t pcibr_dmatrans_direct32(struct pcidev_info * info, u64 paddr, size_t req_size, u64 flags) { - struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> pdi_pcibus_info; @@ -171,7 +169,6 @@ pcibr_dmatrans_direct32(struct pcidev_info * info, } return PCI32_DIRECT_BASE | offset; - } /* @@ -218,9 +215,8 @@ void sn_dma_flush(u64 addr) u64 flags; u64 itte; struct hubdev_info *hubinfo; - volatile struct sn_flush_device_kernel *p; - volatile struct sn_flush_device_common *common; - + struct sn_flush_device_kernel *p; + struct sn_flush_device_common *common; struct sn_flush_nasid_entry *flush_nasid_list; if (!sn_ioif_inited) @@ -310,8 +306,7 @@ void sn_dma_flush(u64 addr) (common->sfdl_slot - 1)); } } else { - spin_lock_irqsave((spinlock_t *)&p->sfdl_flush_lock, - flags); + spin_lock_irqsave(&p->sfdl_flush_lock, flags); *common->sfdl_flush_addr = 0; /* force an interrupt. */ @@ -322,8 +317,7 @@ void sn_dma_flush(u64 addr) cpu_relax(); /* okay, everything is synched up. */ - spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock, - flags); + spin_unlock_irqrestore(&p->sfdl_flush_lock, flags); } return; } diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 2fac270..98f716b 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -163,9 +163,12 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont /* Setup the PMU ATE map */ soft->pbi_int_ate_resource.lowest_free_index = 0; soft->pbi_int_ate_resource.ate = - kmalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); - memset(soft->pbi_int_ate_resource.ate, 0, - (soft->pbi_int_ate_size * sizeof(u64))); + kzalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); + + if (!soft->pbi_int_ate_resource.ate) { + kfree(soft); + return NULL; + } if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { /* TIO PCI Bridge: find nearest node with CPUs */ diff --git a/include/asm-ia64/sn/bte.h b/include/asm-ia64/sn/bte.h index 01e5b41..5335d87 100644 --- a/include/asm-ia64/sn/bte.h +++ b/include/asm-ia64/sn/bte.h @@ -46,7 +46,7 @@ #define BTES_PER_NODE (is_shub2() ? 4 : 2) #define MAX_BTES_PER_NODE 4 -#define BTE2OFF_CTRL (0) +#define BTE2OFF_CTRL 0 #define BTE2OFF_SRC (SH2_BT_ENG_SRC_ADDR_0 - SH2_BT_ENG_CSR_0) #define BTE2OFF_DEST (SH2_BT_ENG_DEST_ADDR_0 - SH2_BT_ENG_CSR_0) #define BTE2OFF_NOTIFY (SH2_BT_ENG_NOTIF_ADDR_0 - SH2_BT_ENG_CSR_0) @@ -75,11 +75,11 @@ : base + (BTEOFF_NOTIFY/8)) /* Define hardware modes */ -#define BTE_NOTIFY (IBCT_NOTIFY) +#define BTE_NOTIFY IBCT_NOTIFY #define BTE_NORMAL BTE_NOTIFY #define BTE_ZERO_FILL (BTE_NOTIFY | IBCT_ZFIL_MODE) /* Use a reserved bit to let the caller specify a wait for any BTE */ -#define BTE_WACQUIRE (0x4000) +#define BTE_WACQUIRE 0x4000 /* Use the BTE on the node with the destination memory */ #define BTE_USE_DEST (BTE_WACQUIRE << 1) /* Use any available BTE interface on any node for the transfer */ diff --git a/include/asm-ia64/sn/pcibr_provider.h b/include/asm-ia64/sn/pcibr_provider.h index 9334078..a601d3a 100644 --- a/include/asm-ia64/sn/pcibr_provider.h +++ b/include/asm-ia64/sn/pcibr_provider.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All rights reserved. */ #ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H #define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H @@ -115,18 +115,6 @@ struct pcibus_info { spinlock_t pbi_lock; }; -/* - * pcibus_info structure locking macros - */ -inline static unsigned long -pcibr_lock(struct pcibus_info *pcibus_info) -{ - unsigned long flag; - spin_lock_irqsave(&pcibus_info->pbi_lock, flag); - return(flag); -} -#define pcibr_unlock(pcibus_info, flag) spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag) - extern int pcibr_init_provider(void); extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *); extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t); diff --git a/include/asm-ia64/sn/sn_feature_sets.h b/include/asm-ia64/sn/sn_feature_sets.h index 9ca642c..ff33e3b 100644 --- a/include/asm-ia64/sn/sn_feature_sets.h +++ b/include/asm-ia64/sn/sn_feature_sets.h @@ -12,9 +12,6 @@ */ -#include -#include - /* --------------------- PROM Features -----------------------------*/ extern int sn_prom_feature_available(int id); -- cgit v0.10.2 From d3454344b3507042e5d561d0cfed19e99cf2fc88 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 13 Feb 2006 05:32:09 -0500 Subject: [IA64] remove obsolete corporate address Remove obsolete SGI address Signed-off-by: Jes Sorensen Signed-off-by: Tony Luck diff --git a/arch/ia64/sn/kernel/sn2/timer_interrupt.c b/arch/ia64/sn/kernel/sn2/timer_interrupt.c index adf5db2..fa7f699 100644 --- a/arch/ia64/sn/kernel/sn2/timer_interrupt.c +++ b/arch/ia64/sn/kernel/sn2/timer_interrupt.c @@ -1,7 +1,7 @@ /* * * - * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2005, 2006 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -22,11 +22,6 @@ * License along with this program; if not, write the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 2b286e8..43b96e2 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -13,11 +13,6 @@ * License along with this program; if not, write the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan diff --git a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h index e1b6cd63..03d00fa 100644 --- a/include/asm-ia64/machvec_sn2.h +++ b/include/asm-ia64/machvec_sn2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2002-2003, 2006 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -20,11 +20,6 @@ * License along with this program; if not, write the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan -- cgit v0.10.2 From 26d10915de3030a55253dba3b2b145402cdf6429 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 13 Feb 2006 05:35:01 -0500 Subject: [IA64-SGI] remove compile time warning This one falls into the "present for Andrew Morton" category to address his wishlist for a compiler warning free build ;-) Signed-off-by: Tony Luck diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 48645ac..1672eca 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -317,6 +317,7 @@ struct pcdp_vga_device { #define PCDP_PCI_TRANS_IOPORT 0x02 #define PCDP_PCI_TRANS_MMIO 0x01 +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) static void sn_scan_pcdp(void) { @@ -358,6 +359,7 @@ sn_scan_pcdp(void) break; /* once we find the primary, we're done */ } } +#endif static unsigned long sn2_rtc_initial; -- cgit v0.10.2 From 9c65cb9be62ac4993a5b392304b82e4f04f010fd Mon Sep 17 00:00:00 2001 From: Mark Maule Date: Tue, 14 Feb 2006 10:23:37 -0600 Subject: [IA64-SGI] export sn_pcidev_info_get Export sn_pcidev_info_get. Signed-off-by Mark Maule Signed-off-by: Tony Luck diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index dfb3f29..3edef0d 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -716,3 +716,4 @@ EXPORT_SYMBOL(sn_pci_unfixup_slot); EXPORT_SYMBOL(sn_pci_controller_fixup); EXPORT_SYMBOL(sn_bus_store_sysdata); EXPORT_SYMBOL(sn_bus_free_sysdata); +EXPORT_SYMBOL(sn_pcidev_info_get); -- cgit v0.10.2 From c2a4969ba14e852bf4ee92c7db3b0cf82405a0c9 Mon Sep 17 00:00:00 2001 From: Dean Roe Date: Tue, 14 Feb 2006 15:01:23 -0600 Subject: [IA64-SGI] fix the size of __sn_cnodeid_to_nasid The __sn_cnodeid_to_nasid array was incorrectly sized at MAX_NUMNODES. On a large system, this array could overflow. The following patch corrects this by defining it to MAX_COMPACT_NODES. Signed-off-by: Dean Roe Signed-off-by: Tony Luck diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 1672eca..5b84836 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -75,7 +75,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second); DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); EXPORT_PER_CPU_SYMBOL(__sn_hub_info); -DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]); +DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h index 1a3831c..91c31be 100644 --- a/include/asm-ia64/sn/arch.h +++ b/include/asm-ia64/sn/arch.h @@ -70,7 +70,7 @@ DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); * Compact node ID to nasid mappings kept in the per-cpu data areas of each * cpu. */ -DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]); +DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); #define sn_cnodeid_to_nasid (&__get_cpu_var(__sn_cnodeid_to_nasid[0])) -- cgit v0.10.2 From 4c2cd96696ae0896ce4bcf725b9f0eaffafeb640 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Wed, 15 Feb 2006 08:02:21 -0600 Subject: [IA64-SGI] enforce proper ordering of callouts by XPC Fix XPC so that it does not deliver any messages until the connected callout has returned, as well as, prevent the disconnected callout to occur before the disconnecting callout has returned. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 36e5437..cdf6856 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c @@ -738,7 +738,9 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) /* make sure all activity has settled down first */ - if (atomic_read(&ch->references) > 0) { + if (atomic_read(&ch->references) > 0 || + ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && + !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE))) { return; } DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0); @@ -775,7 +777,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) /* both sides are disconnected now */ - if (ch->flags & XPC_C_CONNECTCALLOUT) { + if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) { spin_unlock_irqrestore(&ch->lock, *irq_flags); xpc_disconnect_callout(ch, xpcDisconnected); spin_lock_irqsave(&ch->lock, *irq_flags); @@ -1300,7 +1302,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) "delivered=%d, partid=%d, channel=%d\n", nmsgs_sent, ch->partid, ch->number); - if (ch->flags & XPC_C_CONNECTCALLOUT) { + if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) { xpc_activate_kthreads(ch, nmsgs_sent); } } diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index 9cd460d..8cbf164 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c @@ -750,12 +750,16 @@ xpc_daemonize_kthread(void *args) /* let registerer know that connection has been established */ spin_lock_irqsave(&ch->lock, irq_flags); - if (!(ch->flags & XPC_C_CONNECTCALLOUT)) { - ch->flags |= XPC_C_CONNECTCALLOUT; + if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) { + ch->flags |= XPC_C_CONNECTEDCALLOUT; spin_unlock_irqrestore(&ch->lock, irq_flags); xpc_connected_callout(ch); + spin_lock_irqsave(&ch->lock, irq_flags); + ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE; + spin_unlock_irqrestore(&ch->lock, irq_flags); + /* * It is possible that while the callout was being * made that the remote partition sent some messages. @@ -777,15 +781,17 @@ xpc_daemonize_kthread(void *args) if (atomic_dec_return(&ch->kthreads_assigned) == 0) { spin_lock_irqsave(&ch->lock, irq_flags); - if ((ch->flags & XPC_C_CONNECTCALLOUT) && - !(ch->flags & XPC_C_DISCONNECTCALLOUT)) { - ch->flags |= XPC_C_DISCONNECTCALLOUT; + if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && + !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) { + ch->flags |= XPC_C_DISCONNECTINGCALLOUT; spin_unlock_irqrestore(&ch->lock, irq_flags); xpc_disconnect_callout(ch, xpcDisconnecting); - } else { - spin_unlock_irqrestore(&ch->lock, irq_flags); + + spin_lock_irqsave(&ch->lock, irq_flags); + ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE; } + spin_unlock_irqrestore(&ch->lock, irq_flags); if (atomic_dec_return(&part->nchannels_engaged) == 0) { xpc_mark_partition_disengaged(part); xpc_IPI_send_disengage(part); diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h index 0c36928..df7f5f4 100644 --- a/include/asm-ia64/sn/xpc.h +++ b/include/asm-ia64/sn/xpc.h @@ -508,19 +508,24 @@ struct xpc_channel { #define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ #define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ -#define XPC_C_CONNECTCALLOUT 0x00000040 /* channel connected callout made */ -#define XPC_C_CONNECTED 0x00000080 /* local channel is connected */ -#define XPC_C_CONNECTING 0x00000100 /* channel is being connected */ - -#define XPC_C_RCLOSEREPLY 0x00000200 /* remote close channel reply */ -#define XPC_C_CLOSEREPLY 0x00000400 /* local close channel reply */ -#define XPC_C_RCLOSEREQUEST 0x00000800 /* remote close channel request */ -#define XPC_C_CLOSEREQUEST 0x00001000 /* local close channel request */ - -#define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ -#define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ -#define XPC_C_DISCONNECTCALLOUT 0x00008000 /* chan disconnected callout made */ -#define XPC_C_WDISCONNECT 0x00010000 /* waiting for channel disconnect */ +#define XPC_C_CONNECTEDCALLOUT 0x00000040 /* connected callout initiated */ +#define XPC_C_CONNECTEDCALLOUT_MADE \ + 0x00000080 /* connected callout completed */ +#define XPC_C_CONNECTED 0x00000100 /* local channel is connected */ +#define XPC_C_CONNECTING 0x00000200 /* channel is being connected */ + +#define XPC_C_RCLOSEREPLY 0x00000400 /* remote close channel reply */ +#define XPC_C_CLOSEREPLY 0x00000800 /* local close channel reply */ +#define XPC_C_RCLOSEREQUEST 0x00001000 /* remote close channel request */ +#define XPC_C_CLOSEREQUEST 0x00002000 /* local close channel request */ + +#define XPC_C_DISCONNECTED 0x00004000 /* channel is disconnected */ +#define XPC_C_DISCONNECTING 0x00008000 /* channel is being disconnected */ +#define XPC_C_DISCONNECTINGCALLOUT \ + 0x00010000 /* disconnecting callout initiated */ +#define XPC_C_DISCONNECTINGCALLOUT_MADE \ + 0x00020000 /* disconnecting callout completed */ +#define XPC_C_WDISCONNECT 0x00040000 /* waiting for channel disconnect */ -- cgit v0.10.2 From defbb2c929cbe89dc92239b303cd33d3c85e9a83 Mon Sep 17 00:00:00 2001 From: "hawkes@sgi.com" Date: Tue, 14 Feb 2006 10:40:17 -0800 Subject: [IA64] ia64: simplify and fix udelay() The original ia64 udelay() was simple, but flawed for platforms without synchronized ITCs: a preemption and migration to another CPU during the while-loop likely resulted in too-early termination or very, very lengthy looping. The first fix (now in 2.6.15) broke the delay loop into smaller, non-preemptible chunks, reenabling preemption between the chunks. This fix is flawed in that the total udelay is computed to be the sum of just the non-premptible while-loop pieces, i.e., not counting the time spent in the interim preemptible periods. If an interrupt or a migration occurs during one of these interim periods, then that time is invisible and only serves to lengthen the effective udelay(). This new fix backs out the current flawed fix and returns to a simple udelay(), fully preemptible and interruptible. It implements two simple alternative udelay() routines: one a default generic version that uses ia64_get_itc(), and the other an sn-specific version that uses that platform's RTC. Signed-off-by: John Hawkes Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index a094ec4..307d01e 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -250,32 +250,27 @@ time_init (void) set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); } -#define SMALLUSECS 100 - -void -udelay (unsigned long usecs) +/* + * Generic udelay assumes that if preemption is allowed and the thread + * migrates to another CPU, that the ITC values are synchronized across + * all CPUs. + */ +static void +ia64_itc_udelay (unsigned long usecs) { - unsigned long start; - unsigned long cycles; - unsigned long smallusecs; + unsigned long start = ia64_get_itc(); + unsigned long end = start + usecs*local_cpu_data->cyc_per_usec; - /* - * Execute the non-preemptible delay loop (because the ITC might - * not be synchronized between CPUS) in relatively short time - * chunks, allowing preemption between the chunks. - */ - while (usecs > 0) { - smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs; - preempt_disable(); - cycles = smallusecs*local_cpu_data->cyc_per_usec; - start = ia64_get_itc(); + while (time_before(ia64_get_itc(), end)) + cpu_relax(); +} - while (ia64_get_itc() - start < cycles) - cpu_relax(); +void (*ia64_udelay)(unsigned long usecs) = &ia64_itc_udelay; - preempt_enable(); - usecs -= smallusecs; - } +void +udelay (unsigned long usecs) +{ + (*ia64_udelay)(usecs); } EXPORT_SYMBOL(udelay); diff --git a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c index deb9baf..56a88b6 100644 --- a/arch/ia64/sn/kernel/sn2/timer.c +++ b/arch/ia64/sn/kernel/sn2/timer.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -28,9 +29,27 @@ static struct time_interpolator sn2_interpolator = { .source = TIME_SOURCE_MMIO64 }; +/* + * sn udelay uses the RTC instead of the ITC because the ITC is not + * synchronized across all CPUs, and the thread may migrate to another CPU + * if preemption is enabled. + */ +static void +ia64_sn_udelay (unsigned long usecs) +{ + unsigned long start = rtc_time(); + unsigned long end = start + + usecs * sn_rtc_cycles_per_second / 1000000; + + while (time_before((unsigned long)rtc_time(), end)) + cpu_relax(); +} + void __init sn_timer_init(void) { sn2_interpolator.frequency = sn_rtc_cycles_per_second; sn2_interpolator.addr = RTC_COUNTER_ADDR; register_time_interpolator(&sn2_interpolator); + + ia64_udelay = &ia64_sn_udelay; } diff --git a/include/asm-ia64/timex.h b/include/asm-ia64/timex.h index 414aae0..05a6baf 100644 --- a/include/asm-ia64/timex.h +++ b/include/asm-ia64/timex.h @@ -15,6 +15,8 @@ typedef unsigned long cycles_t; +extern void (*ia64_udelay)(unsigned long usecs); + /* * For performance reasons, we don't want to define CLOCK_TICK_TRATE as * local_cpu_data->itc_rate. Fortunately, we don't have to, either: according to George -- cgit v0.10.2 From 48d5cad87c3a4998d0bda16ccfb5c60dfe4de5fb Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 15 Feb 2006 15:10:22 -0800 Subject: [XFRM]: Fix SNAT-related crash in xfrm4_output_finish When a packet matching an IPsec policy is SNATed so it doesn't match any policy anymore it looses its xfrm bundle, which makes xfrm4_output_finish crash because of a NULL pointer dereference. This patch directs these packets to the original output path instead. Since the packets have already passed the POST_ROUTING hook, but need to start at the beginning of the original output path which includes another POST_ROUTING invocation, a flag is added to the IPCB to indicate that the packet was rerouted and doesn't need to pass the POST_ROUTING hook again. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 4cf6088..3ca3d9e 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -184,8 +184,11 @@ static inline int nf_hook_thresh(int pf, unsigned int hook, struct sk_buff **pskb, struct net_device *indev, struct net_device *outdev, - int (*okfn)(struct sk_buff *), int thresh) + int (*okfn)(struct sk_buff *), int thresh, + int cond) { + if (!cond) + return 1; #ifndef CONFIG_NETFILTER_DEBUG if (list_empty(&nf_hooks[pf][hook])) return 1; @@ -197,7 +200,7 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *)) { - return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN); + return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN, 1); } /* Activate hook; either okfn or kfree_skb called, unless a hook @@ -224,7 +227,13 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb, #define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \ ({int __ret; \ -if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)\ +if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\ + __ret = (okfn)(skb); \ +__ret;}) + +#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \ +({int __ret; \ +if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\ __ret = (okfn)(skb); \ __ret;}) @@ -295,11 +304,13 @@ extern struct proc_dir_entry *proc_net_netfilter; #else /* !CONFIG_NETFILTER */ #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) +#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb) static inline int nf_hook_thresh(int pf, unsigned int hook, struct sk_buff **pskb, struct net_device *indev, struct net_device *outdev, - int (*okfn)(struct sk_buff *), int thresh) + int (*okfn)(struct sk_buff *), int thresh, + int cond) { return okfn(*pskb); } diff --git a/include/net/ip.h b/include/net/ip.h index 8de0697..fab3d5b 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -41,6 +41,7 @@ struct inet_skb_parm #define IPSKB_XFRM_TUNNEL_SIZE 2 #define IPSKB_XFRM_TRANSFORMED 4 #define IPSKB_FRAG_COMPLETE 8 +#define IPSKB_REROUTED 16 }; struct ipcm_cookie diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d09ca0e..d6111a2 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -866,7 +866,6 @@ extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); extern int xfrm_init_state(struct xfrm_state *x); extern int xfrm4_rcv(struct sk_buff *skb); extern int xfrm4_output(struct sk_buff *skb); -extern int xfrm4_output_finish(struct sk_buff *skb); extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); extern int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index abe2392..9981dcd 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -830,7 +830,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) skb->h.raw = skb->nh.raw; skb->nh.raw = skb_push(skb, gre_hlen); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); - IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | + IPSKB_REROUTED); dst_release(skb->dst); skb->dst = &rt->u.dst; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3324fbf..57d290d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -207,8 +207,10 @@ static inline int ip_finish_output(struct sk_buff *skb) { #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) /* Policy lookup after SNAT yielded a new policy */ - if (skb->dst->xfrm != NULL) - return xfrm4_output_finish(skb); + if (skb->dst->xfrm != NULL) { + IPCB(skb)->flags |= IPSKB_REROUTED; + return dst_output(skb); + } #endif if (skb->len > dst_mtu(skb->dst) && !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) @@ -271,8 +273,9 @@ int ip_mc_output(struct sk_buff *skb) newskb->dev, ip_dev_loopback_xmit); } - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, - ip_finish_output); + return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, + ip_finish_output, + !(IPCB(skb)->flags & IPSKB_REROUTED)); } int ip_output(struct sk_buff *skb) @@ -284,8 +287,9 @@ int ip_output(struct sk_buff *skb) skb->dev = dev; skb->protocol = htons(ETH_P_IP); - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, - ip_finish_output); + return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, + ip_finish_output, + !(IPCB(skb)->flags & IPSKB_REROUTED)); } int ip_queue_xmit(struct sk_buff *skb, int ipfragok) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e5cbe72..03d1374 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -622,7 +622,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) skb->h.raw = skb->nh.raw; skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); - IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | + IPSKB_REROUTED); dst_release(skb->dst); skb->dst = &rt->u.dst; diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index d4df0dd..32ad229 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -152,10 +152,16 @@ error_nolock: goto out_exit; } -int xfrm4_output_finish(struct sk_buff *skb) +static int xfrm4_output_finish(struct sk_buff *skb) { int err; +#ifdef CONFIG_NETFILTER + if (!skb->dst->xfrm) { + IPCB(skb)->flags |= IPSKB_REROUTED; + return dst_output(skb); + } +#endif while (likely((err = xfrm4_output_one(skb)) == 0)) { nf_reset(skb); @@ -178,6 +184,7 @@ int xfrm4_output_finish(struct sk_buff *skb) int xfrm4_output(struct sk_buff *skb) { - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, - xfrm4_output_finish); + return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, + xfrm4_output_finish, + !(IPCB(skb)->flags & IPSKB_REROUTED)); } -- cgit v0.10.2 From b05de01ae1c76b7d61da21bbcc26345bf7a9052f Mon Sep 17 00:00:00 2001 From: Horms Date: Wed, 15 Feb 2006 17:23:09 +0900 Subject: [IA64] support panic_on_oops sysctl Trivial port of this feature from i386 As it stands, panic_on_oops but does nothing on ia64 Signed-Off-By: Horms Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 5539190..dabd6c3 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -16,6 +16,7 @@ #include /* for EXPORT_SYMBOL */ #include #include +#include /* for ssleep() */ #include #include @@ -116,6 +117,13 @@ die (const char *str, struct pt_regs *regs, long err) bust_spinlocks(0); die.lock_owner = -1; spin_unlock_irq(&die.lock); + + if (panic_on_oops) { + printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); + ssleep(5); + panic("Fatal exception"); + } + do_exit(SIGSEGV); } -- cgit v0.10.2 From 9c92d3486434e7310cb288587953e2dae4a79701 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 15 Feb 2006 15:18:19 -0800 Subject: [NETFILTER]: Don't invoke okfn in CONFIG_NETFILTER=n variant of nf_hook() nf_hook() is supposed to call the netfilter hook and return control of the packet back to the caller in case it may pass, the okfn is only used for queueing. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 3ca3d9e..4688969 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -318,7 +318,7 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *)) { - return okfn(*pskb); + return 1; } static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} struct flowi; -- cgit v0.10.2 From deac0ccdb4da16b68539d75edecf26162de05150 Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Wed, 15 Feb 2006 15:21:31 -0800 Subject: [NETFILTER]: x_tables: fix dependencies of conntrack related modules NF_CONNTRACK_MARK is bool and depends on NF_CONNTRACK which is tristate. If a variable depends on NF_CONNTRACK_MARK and doesn't take care about NF_CONNTRACK, it can be y even if NF_CONNTRACK isn't y. NF_CT_ACCT have same issue, too. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 0e55012..a8e5544 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -126,7 +126,7 @@ config NETFILTER_XT_TARGET_CONNMARK tristate '"CONNMARK" target support' depends on NETFILTER_XTABLES depends on IP_NF_MANGLE || IP6_NF_MANGLE - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK) help This option adds a `CONNMARK' target, which allows one to manipulate the connection mark value. Similar to the MARK target, but @@ -187,7 +187,7 @@ config NETFILTER_XT_MATCH_COMMENT config NETFILTER_XT_MATCH_CONNBYTES tristate '"connbytes" per-connection counter match support' depends on NETFILTER_XTABLES - depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT + depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK) help This option adds a `connbytes' match, which allows you to match the number of bytes and/or packets for each direction within a connection. @@ -198,7 +198,7 @@ config NETFILTER_XT_MATCH_CONNBYTES config NETFILTER_XT_MATCH_CONNMARK tristate '"connmark" connection mark match support' depends on NETFILTER_XTABLES - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK) help This option adds a `connmark' match, which allows you to match the connection mark value previously set for the session by `CONNMARK'. -- cgit v0.10.2 From 7d3cdc6b554137a7a0534ce38b155a63a3117f27 Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Wed, 15 Feb 2006 15:22:21 -0800 Subject: [NETFILTER]: nf_conntrack: move registration of __nf_ct_attach Move registration of __nf_ct_attach to nf_conntrack_core to make it usable for IPv6 connection tracking as well. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 167619f..6c8624a 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -529,15 +529,10 @@ static int init_or_cleanup(int init) goto cleanup_localinops; } #endif - - /* For use by REJECT target */ - ip_ct_attach = __nf_conntrack_attach; - return ret; cleanup: synchronize_net(); - ip_ct_attach = NULL; #ifdef CONFIG_SYSCTL unregister_sysctl_table(nf_ct_ipv4_sysctl_header); cleanup_localinops: diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 0ce337a..d622ddf 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1556,6 +1556,8 @@ void nf_conntrack_cleanup(void) { int i; + ip_ct_attach = NULL; + /* This makes sure all current packets have passed through netfilter framework. Roll on, two-stage module delete... */ @@ -1715,6 +1717,9 @@ int __init nf_conntrack_init(void) nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto; write_unlock_bh(&nf_conntrack_lock); + /* For use by REJECT target */ + ip_ct_attach = __nf_conntrack_attach; + /* Set up fake conntrack: - to never be deleted, not in any hashes */ atomic_set(&nf_conntrack_untracked.ct_general.use, 1); -- cgit v0.10.2 From 08857fa745ab6ce46601960d2774490e1cef2cff Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Wed, 15 Feb 2006 15:23:28 -0800 Subject: [NETFILTER]: nf_conntrack: attach conntrack to TCP RST generated by ip6t_REJECT TCP RSTs generated by the REJECT target should be associated with the conntrack of the original TCP packet. Since the conntrack entry is usually not is the hash tables, it must be manually attached. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index c745717..0e6d1d4 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -160,6 +160,8 @@ static void send_reset(struct sk_buff *oldskb) csum_partial((char *)tcph, sizeof(struct tcphdr), 0)); + nf_ct_attach(nskb, oldskb); + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev, dst_output); } -- cgit v0.10.2 From 763ecff1879b3877f57f20fc9e79599aef59359f Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Wed, 15 Feb 2006 15:24:15 -0800 Subject: [NETFILTER]: nf_conntrack: attach conntrack to locally generated ICMPv6 error Locally generated ICMPv6 errors should be associated with the conntrack of the original packet. Since the conntrack entry may not be in the hash tables (for the first packet), it must be manually attached. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index fcf8831..21eb725 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef CONFIG_SYSCTL #include @@ -255,6 +256,7 @@ out: struct icmpv6_msg { struct sk_buff *skb; int offset; + uint8_t type; }; static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) @@ -266,6 +268,8 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, to, len, csum); skb->csum = csum_block_add(skb->csum, csum, odd); + if (!(msg->type & ICMPV6_INFOMSG_MASK)) + nf_ct_attach(skb, org_skb); return 0; } @@ -403,6 +407,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, msg.skb = skb; msg.offset = skb->nh.raw - skb->data; + msg.type = type; len = skb->len - msg.offset; len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr)); @@ -500,6 +505,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) msg.skb = skb; msg.offset = 0; + msg.type = ICMPV6_ECHO_REPLY; err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl, -- cgit v0.10.2 From 7c6de05884b9fcc7ef621e2ab198ba93d85f46aa Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Wed, 15 Feb 2006 15:25:18 -0800 Subject: [NETFILTER]: nf_conntrack: Fix TCP/UDP HW checksum handling for IPv6 packet If skb->ip_summed is CHECKSUM_HW here, skb->csum includes checksum of actual IPv6 header and extension headers. Then such excess checksum must be subtruct when nf_conntrack calculates TCP/UDP checksum with pseudo IPv6 header. Spotted by Ben Skeggs. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index df99138..6492ed6 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -864,7 +864,9 @@ static int csum6(const struct sk_buff *skb, unsigned int dataoff) { return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, skb->len - dataoff, IPPROTO_TCP, - skb->ip_summed == CHECKSUM_HW ? skb->csum + skb->ip_summed == CHECKSUM_HW + ? csum_sub(skb->csum, + skb_checksum(skb, 0, dataoff, 0)) : skb_checksum(skb, dataoff, skb->len - dataoff, 0)); } diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index 4264dd0..831d206 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -161,7 +161,9 @@ static int csum6(const struct sk_buff *skb, unsigned int dataoff) { return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, skb->len - dataoff, IPPROTO_UDP, - skb->ip_summed == CHECKSUM_HW ? skb->csum + skb->ip_summed == CHECKSUM_HW + ? csum_sub(skb->csum, + skb_checksum(skb, 0, dataoff, 0)) : skb_checksum(skb, dataoff, skb->len - dataoff, 0)); } -- cgit v0.10.2 From 9f672004ab1a8094bec1785b39ac683ab9eebebc Mon Sep 17 00:00:00 2001 From: Christian Trefzer Date: Wed, 15 Feb 2006 15:17:34 -0800 Subject: [PATCH] neofb: avoid resetting display config on unblank (v2) There were two mistakes in the register-read-on-(un)blank approach. - First, without proper register (un)locking the value read back will always be zero, and this is what I missed entirely until just now. Due to this, the logic could not be verified at all and I tried some bogus checks which are completely stupid. - Second, the LCD status bit will always be set to zero when the backlight has been turned off. Reading the value back during unblank will disable the LCD unconditionally, regardless of the state it is supposed to be in, since we set it to zero beforehand. So this is what we do now: - create a new variable in struct neofb_par, and use that to determine whether to read back registers (initialized to true) - before actually blanking the screen, read back the register to sense any possible change made through Fn key combo - use proper neoUnlock() / neoLock() to actually read something - every call to neofb_blank() determines if we read back next time: blanking disables readback, unblanking (FB_BLANK_UNBLANK) enables it This should give us a nice and clean state machine. Has been thoroughly tested on a Dell Latitude CPiA / NM220 Chip docked to a C/Dock2 with attached CRT in all possible combinations of LCD/CRT on/off. I changed the config via Fn key, let the console blank, unblanked by keypress - works flawlessly. Signed-off-by: Christian Trefzer Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index b85e2b1..a2e201d 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -843,6 +843,9 @@ static int neofb_set_par(struct fb_info *info) par->SysIfaceCntl2 = 0xc0; /* VESA Bios sets this to 0x80! */ + /* Initialize: by default, we want display config register to be read */ + par->PanelDispCntlRegRead = 1; + /* Enable any user specified display devices. */ par->PanelDispCntlReg1 = 0x00; if (par->internal_display) @@ -1334,11 +1337,17 @@ static int neofb_blank(int blank_mode, struct fb_info *info) struct neofb_par *par = info->par; int seqflags, lcdflags, dpmsflags, reg; + /* - * Reload the value stored in the register, might have been changed via - * FN keystroke + * Reload the value stored in the register, if sensible. It might have + * been changed via FN keystroke. */ - par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; + if (par->PanelDispCntlRegRead) { + neoUnlock(); + par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; + neoLock(&par->state); + } + par->PanelDispCntlRegRead = !blank_mode; switch (blank_mode) { case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ diff --git a/include/video/neomagic.h b/include/video/neomagic.h index 1d69049..78b1f15 100644 --- a/include/video/neomagic.h +++ b/include/video/neomagic.h @@ -159,6 +159,7 @@ struct neofb_par { unsigned char PanelDispCntlReg1; unsigned char PanelDispCntlReg2; unsigned char PanelDispCntlReg3; + unsigned char PanelDispCntlRegRead; unsigned char PanelVertCenterReg1; unsigned char PanelVertCenterReg2; unsigned char PanelVertCenterReg3; -- cgit v0.10.2 From 36cbbe5eb9857730768aa5f54ad94d69e0b2133d Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Wed, 15 Feb 2006 15:17:35 -0800 Subject: [PATCH] kbuild: revert "fix make -jN with multiple targets with O=..." Commit 296e0855b0f9a4ec9be17106ac541745a55b2ce1: "kbuild: fix make -jN with multiple targets with O=..." causes a ~95% increase in build time for the kernel. Before: 4m21s after: 8m1.403s. Can we revert this until another approach is found? Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Makefile b/Makefile index 74d67b2..48d569d 100644 --- a/Makefile +++ b/Makefile @@ -106,13 +106,12 @@ KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd) $(if $(KBUILD_OUTPUT),, \ $(error output directory "$(saved-output)" does not exist)) -.PHONY: $(MAKECMDGOALS) cdbuilddir -$(MAKECMDGOALS) _all: cdbuilddir +.PHONY: $(MAKECMDGOALS) -cdbuilddir: +$(filter-out _all,$(MAKECMDGOALS)) _all: $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \ KBUILD_SRC=$(CURDIR) \ - KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $(MAKECMDGOALS) + KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@ # Leave processing to above invocation of make skip-makefile := 1 -- cgit v0.10.2 From 651c29a17f7ea0204dacbc2a5042d57b1c9e2e37 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 15 Feb 2006 15:17:37 -0800 Subject: [PATCH] ide: touch softlockup detector during pio We're getting some softlockup false positives during heavy PIO operations. So poke the lockup detector. Cc: Bartlomiej Zolnierkiewicz Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 9834dce..0606bd2 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -314,6 +315,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, if (rq->bio) /* fs request */ rq->errors = 0; + touch_softlockup_watchdog(); + switch (drive->hwif->data_phase) { case TASKFILE_MULTI_IN: case TASKFILE_MULTI_OUT: -- cgit v0.10.2 From 06fed33849c13af637c4d09e9ba27828fac9edd5 Mon Sep 17 00:00:00 2001 From: Paul Jackson Date: Wed, 15 Feb 2006 15:17:38 -0800 Subject: [PATCH] cpuset: oops in exit on null cpuset fix Fix a latent bug in cpuset_exit() handling. If a task tried to allocate memory after calling cpuset_exit(), it oops'd in cpuset_update_task_memory_state() on a NULL cpuset pointer. So set the exiting tasks cpuset to the root cpuset instead of to NULL. A distro kernel hit this with an added kernel package that had just such a hook (allocating memory) in the exit code path. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/cpuset.c b/kernel/cpuset.c index ba42b0a..12815d3 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1977,6 +1977,39 @@ void cpuset_fork(struct task_struct *child) * We don't need to task_lock() this reference to tsk->cpuset, * because tsk is already marked PF_EXITING, so attach_task() won't * mess with it, or task is a failed fork, never visible to attach_task. + * + * Hack: + * + * Set the exiting tasks cpuset to the root cpuset (top_cpuset). + * + * Don't leave a task unable to allocate memory, as that is an + * accident waiting to happen should someone add a callout in + * do_exit() after the cpuset_exit() call that might allocate. + * If a task tries to allocate memory with an invalid cpuset, + * it will oops in cpuset_update_task_memory_state(). + * + * We call cpuset_exit() while the task is still competent to + * handle notify_on_release(), then leave the task attached to + * the root cpuset (top_cpuset) for the remainder of its exit. + * + * To do this properly, we would increment the reference count on + * top_cpuset, and near the very end of the kernel/exit.c do_exit() + * code we would add a second cpuset function call, to drop that + * reference. This would just create an unnecessary hot spot on + * the top_cpuset reference count, to no avail. + * + * Normally, holding a reference to a cpuset without bumping its + * count is unsafe. The cpuset could go away, or someone could + * attach us to a different cpuset, decrementing the count on + * the first cpuset that we never incremented. But in this case, + * top_cpuset isn't going away, and either task has PF_EXITING set, + * which wards off any attach_task() attempts, or task is a failed + * fork, never visible to attach_task. + * + * Another way to do this would be to set the cpuset pointer + * to NULL here, and check in cpuset_update_task_memory_state() + * for a NULL pointer. This hack avoids that NULL check, for no + * cost (other than this way too long comment ;). **/ void cpuset_exit(struct task_struct *tsk) @@ -1984,7 +2017,7 @@ void cpuset_exit(struct task_struct *tsk) struct cpuset *cs; cs = tsk->cpuset; - tsk->cpuset = NULL; + tsk->cpuset = &top_cpuset; /* Hack - see comment above */ if (notify_on_release(cs)) { char *pathbuf = NULL; -- cgit v0.10.2 From 5f6164f3092832e0d9b12eed52e09a76bf39c64a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 15 Feb 2006 15:17:39 -0800 Subject: [PATCH] add asm-generic/mman.h Make new MADV_REMOVE, MADV_DONTFORK, MADV_DOFORK consistent across all arches. The idea is to make it possible to use them portably even before distros include them in libc headers. Move common flags to asm-generic/mman.h Signed-off-by: Michael S. Tsirkin Cc: Roland Dreier Cc: Badari Pulavarty Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h index a21515c..5f24c75 100644 --- a/include/asm-alpha/mman.h +++ b/include/asm-alpha/mman.h @@ -42,9 +42,11 @@ #define MADV_WILLNEED 3 /* will need these pages */ #define MADV_SPACEAVAIL 5 /* ensure resources are available */ #define MADV_DONTNEED 6 /* don't need these pages */ -#define MADV_REMOVE 7 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ + +/* common/generic parameters */ +#define MADV_REMOVE 9 /* remove these pages & resources */ +#define MADV_DONTFORK 10 /* don't inherit across fork */ +#define MADV_DOFORK 11 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-arm/mman.h b/include/asm-arm/mman.h index 693ed85..54570d2 100644 --- a/include/asm-arm/mman.h +++ b/include/asm-arm/mman.h @@ -1,19 +1,7 @@ #ifndef __ARM_MMAN_H__ #define __ARM_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -23,24 +11,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) page tables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __ARM_MMAN_H__ */ diff --git a/include/asm-arm26/mman.h b/include/asm-arm26/mman.h index 2096c50..4000a6c 100644 --- a/include/asm-arm26/mman.h +++ b/include/asm-arm26/mman.h @@ -1,19 +1,7 @@ #ifndef __ARM_MMAN_H__ #define __ARM_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -23,24 +11,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) page tables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __ARM_MMAN_H__ */ diff --git a/include/asm-cris/mman.h b/include/asm-cris/mman.h index deddfb2..1c35e1b 100644 --- a/include/asm-cris/mman.h +++ b/include/asm-cris/mman.h @@ -3,19 +3,7 @@ /* verbatim copy of asm-i386/ version */ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -25,24 +13,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __CRIS_MMAN_H__ */ diff --git a/include/asm-frv/mman.h b/include/asm-frv/mman.h index d3bca30..b4371e9 100644 --- a/include/asm-frv/mman.h +++ b/include/asm-frv/mman.h @@ -1,19 +1,7 @@ #ifndef __ASM_MMAN_H__ #define __ASM_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -23,25 +11,8 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __ASM_MMAN_H__ */ diff --git a/include/asm-generic/mman.h b/include/asm-generic/mman.h new file mode 100644 index 0000000..3b41d2b --- /dev/null +++ b/include/asm-generic/mman.h @@ -0,0 +1,42 @@ +#ifndef _ASM_GENERIC_MMAN_H +#define _ASM_GENERIC_MMAN_H + +/* + Author: Michael S. Tsirkin , Mellanox Technologies Ltd. + Based on: asm-xxx/mman.h +*/ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MADV_NORMAL 0 /* no further special treatment */ +#define MADV_RANDOM 1 /* expect random page references */ +#define MADV_SEQUENTIAL 2 /* expect sequential page references */ +#define MADV_WILLNEED 3 /* will need these pages */ +#define MADV_DONTNEED 4 /* don't need these pages */ + +/* common parameters: try to keep these consistent across architectures */ +#define MADV_REMOVE 9 /* remove these pages & resources */ +#define MADV_DONTFORK 10 /* don't inherit across fork */ +#define MADV_DOFORK 11 /* do inherit across fork */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h index ac0346f..b9f104f 100644 --- a/include/asm-h8300/mman.h +++ b/include/asm-h8300/mman.h @@ -1,19 +1,7 @@ #ifndef __H8300_MMAN_H__ #define __H8300_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -23,24 +11,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __H8300_MMAN_H__ */ diff --git a/include/asm-i386/mman.h b/include/asm-i386/mman.h index ab2339a..8fd9d7a 100644 --- a/include/asm-i386/mman.h +++ b/include/asm-i386/mman.h @@ -1,19 +1,7 @@ #ifndef __I386_MMAN_H__ #define __I386_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -23,24 +11,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __I386_MMAN_H__ */ diff --git a/include/asm-ia64/mman.h b/include/asm-ia64/mman.h index 357ebb7..6ba179f 100644 --- a/include/asm-ia64/mman.h +++ b/include/asm-ia64/mman.h @@ -8,19 +8,7 @@ * David Mosberger-Tang , Hewlett-Packard Co */ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x00100 /* stack-like segment */ #define MAP_GROWSUP 0x00200 /* register stack-like segment */ @@ -31,24 +19,7 @@ #define MAP_POPULATE 0x08000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* _ASM_IA64_MMAN_H */ diff --git a/include/asm-m32r/mman.h b/include/asm-m32r/mman.h index 6b02fe3..695a860 100644 --- a/include/asm-m32r/mman.h +++ b/include/asm-m32r/mman.h @@ -1,21 +1,9 @@ #ifndef __M32R_MMAN_H__ #define __M32R_MMAN_H__ -/* orig : i386 2.6.0-test6 */ - -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ +#include -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +/* orig : i386 2.6.0-test6 */ #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -25,24 +13,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __M32R_MMAN_H__ */ diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h index efd12bc..1626d37 100644 --- a/include/asm-m68k/mman.h +++ b/include/asm-m68k/mman.h @@ -1,19 +1,7 @@ #ifndef __M68K_MMAN_H__ #define __M68K_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -23,24 +11,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __M68K_MMAN_H__ */ diff --git a/include/asm-mips/mman.h b/include/asm-mips/mman.h index 6d01e26..046cf68 100644 --- a/include/asm-mips/mman.h +++ b/include/asm-mips/mman.h @@ -60,17 +60,19 @@ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ +#define MADV_NORMAL 0 /* no further special treatment */ +#define MADV_RANDOM 1 /* expect random page references */ +#define MADV_SEQUENTIAL 2 /* expect sequential page references */ +#define MADV_WILLNEED 3 /* will need these pages */ +#define MADV_DONTNEED 4 /* don't need these pages */ + +/* common parameters: try to keep these consistent across architectures */ +#define MADV_REMOVE 9 /* remove these pages & resources */ +#define MADV_DONTFORK 10 /* don't inherit across fork */ +#define MADV_DOFORK 11 /* do inherit across fork */ /* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 #endif /* _ASM_MMAN_H */ diff --git a/include/asm-parisc/mman.h b/include/asm-parisc/mman.h index a381cf5..0ef15ee 100644 --- a/include/asm-parisc/mman.h +++ b/include/asm-parisc/mman.h @@ -38,7 +38,11 @@ #define MADV_SPACEAVAIL 5 /* insure that resources are reserved */ #define MADV_VPS_PURGE 6 /* Purge pages from VM page cache */ #define MADV_VPS_INHERIT 7 /* Inherit parents page size */ -#define MADV_REMOVE 8 /* remove these pages & resources */ + +/* common/generic parameters */ +#define MADV_REMOVE 9 /* remove these pages & resources */ +#define MADV_DONTFORK 10 /* don't inherit across fork */ +#define MADV_DOFORK 11 /* do inherit across fork */ /* The range 12-64 is reserved for page size specification. */ #define MADV_4K_PAGES 12 /* Use 4K pages */ @@ -49,8 +53,6 @@ #define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */ #define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */ #define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ /* compatibility flags */ #define MAP_ANON MAP_ANONYMOUS diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h index fcff25d..24cf664 100644 --- a/include/asm-powerpc/mman.h +++ b/include/asm-powerpc/mman.h @@ -1,6 +1,8 @@ #ifndef _ASM_POWERPC_MMAN_H #define _ASM_POWERPC_MMAN_H +#include + /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -8,19 +10,6 @@ * 2 of the License, or (at your option) any later version. */ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ #define MAP_NORESERVE 0x40 /* don't reserve swap pages */ #define MAP_LOCKED 0x80 @@ -29,27 +18,10 @@ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ #define MCL_FUTURE 0x4000 /* lock all additions to address space */ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* _ASM_POWERPC_MMAN_H */ diff --git a/include/asm-s390/mman.h b/include/asm-s390/mman.h index d41ca14..7839767 100644 --- a/include/asm-s390/mman.h +++ b/include/asm-s390/mman.h @@ -9,19 +9,7 @@ #ifndef __S390_MMAN_H__ #define __S390_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -31,24 +19,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __S390_MMAN_H__ */ diff --git a/include/asm-sh/mman.h b/include/asm-sh/mman.h index 0e08d05..156eb02 100644 --- a/include/asm-sh/mman.h +++ b/include/asm-sh/mman.h @@ -1,19 +1,7 @@ #ifndef __ASM_SH_MMAN_H #define __ASM_SH_MMAN_H -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -23,24 +11,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) page tables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __ASM_SH_MMAN_H */ diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h index 4a298b2..88d1886 100644 --- a/include/asm-sparc/mman.h +++ b/include/asm-sparc/mman.h @@ -2,21 +2,10 @@ #ifndef __SPARC_MMAN_H__ #define __SPARC_MMAN_H__ -/* SunOS'ified... */ +#include -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ +/* SunOS'ified... */ -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ #define MAP_NORESERVE 0x40 /* don't reserve swap pages */ #define MAP_INHERIT 0x80 /* SunOS doesn't do this, but... */ @@ -27,10 +16,6 @@ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ #define MCL_FUTURE 0x4000 /* lock all additions to address space */ @@ -48,18 +33,6 @@ #define MC_LOCKAS 5 /* Lock an entire address space of the calling process */ #define MC_UNLOCKAS 6 /* Unlock entire address space of calling process */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_FREE 0x5 /* (Solaris) contents can be freed */ -#define MADV_REMOVE 0x6 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 #endif /* __SPARC_MMAN_H__ */ diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h index d705ec9..6fd878e 100644 --- a/include/asm-sparc64/mman.h +++ b/include/asm-sparc64/mman.h @@ -2,21 +2,10 @@ #ifndef __SPARC64_MMAN_H__ #define __SPARC64_MMAN_H__ -/* SunOS'ified... */ +#include -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ +/* SunOS'ified... */ -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ #define MAP_NORESERVE 0x40 /* don't reserve swap pages */ #define MAP_INHERIT 0x80 /* SunOS doesn't do this, but... */ @@ -27,10 +16,6 @@ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ #define MCL_FUTURE 0x4000 /* lock all additions to address space */ @@ -48,18 +33,6 @@ #define MC_LOCKAS 5 /* Lock an entire address space of the calling process */ #define MC_UNLOCKAS 6 /* Unlock entire address space of calling process */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ #define MADV_FREE 0x5 /* (Solaris) contents can be freed */ -#define MADV_REMOVE 0x6 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 #endif /* __SPARC64_MMAN_H__ */ diff --git a/include/asm-v850/mman.h b/include/asm-v850/mman.h index 7b851c3..edbf6ed 100644 --- a/include/asm-v850/mman.h +++ b/include/asm-v850/mman.h @@ -1,18 +1,7 @@ #ifndef __V850_MMAN_H__ #define __V850_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ @@ -20,24 +9,7 @@ #define MAP_LOCKED 0x2000 /* pages are locked */ #define MAP_NORESERVE 0x4000 /* don't check for reservations */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif /* __V850_MMAN_H__ */ diff --git a/include/asm-x86_64/mman.h b/include/asm-x86_64/mman.h index b699a38..dd5cb05 100644 --- a/include/asm-x86_64/mman.h +++ b/include/asm-x86_64/mman.h @@ -1,19 +1,8 @@ #ifndef __X8664_MMAN_H__ #define __X8664_MMAN_H__ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_SEM 0x8 -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ +#include -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ #define MAP_32BIT 0x40 /* only give out 32bit addresses */ #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ @@ -24,24 +13,7 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - #endif diff --git a/include/asm-xtensa/mman.h b/include/asm-xtensa/mman.h index e2d7afb..ba394cb 100644 --- a/include/asm-xtensa/mman.h +++ b/include/asm-xtensa/mman.h @@ -67,17 +67,19 @@ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#define MADV_DONTFORK 0x30 /* dont inherit across fork */ -#define MADV_DOFORK 0x31 /* do inherit across fork */ +#define MADV_NORMAL 0 /* no further special treatment */ +#define MADV_RANDOM 1 /* expect random page references */ +#define MADV_SEQUENTIAL 2 /* expect sequential page references */ +#define MADV_WILLNEED 3 /* will need these pages */ +#define MADV_DONTNEED 4 /* don't need these pages */ + +/* common parameters: try to keep these consistent across architectures */ +#define MADV_REMOVE 9 /* remove these pages & resources */ +#define MADV_DONTFORK 10 /* don't inherit across fork */ +#define MADV_DOFORK 11 /* do inherit across fork */ /* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 #endif /* _XTENSA_MMAN_H */ -- cgit v0.10.2 From b2ee9dbfad14ba8e34a589d552ddc67300a26bec Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Wed, 15 Feb 2006 15:17:40 -0800 Subject: [PATCH] hrtimer: fix multiple macro argument expansion For two macros the arguments were expanded twice, change them to inline functions to avoid it. Signed-off-by: Roman Zippel Acked-by: Ingo Molnar Acked-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 6aca67a..f3dec45 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -96,10 +96,16 @@ static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; }) /* convert a timespec to ktime_t format: */ -#define timespec_to_ktime(ts) ktime_set((ts).tv_sec, (ts).tv_nsec) +static inline ktime_t timespec_to_ktime(struct timespec ts) +{ + return ktime_set(ts.tv_sec, ts.tv_nsec); +} /* convert a timeval to ktime_t format: */ -#define timeval_to_ktime(tv) ktime_set((tv).tv_sec, (tv).tv_usec * 1000) +static inline ktime_t timeval_to_ktime(struct timeval tv) +{ + return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC); +} /* Map the ktime_t to timespec conversion to ns_to_timespec function */ #define ktime_to_timespec(kt) ns_to_timespec((kt).tv64) -- cgit v0.10.2 From d1db4ec86c7b1bf5b44d2ed3bf84a4bb53c33b1c Mon Sep 17 00:00:00 2001 From: Daniel Yeisley Date: Wed, 15 Feb 2006 15:17:41 -0800 Subject: [PATCH] x86_64: early initialization of cpu_to_node The early initialization of cpu_to_node code as it is now only updates the cpu_to_node array, and does not update cpu_pda()->nodemember. This will cause numa_node_id() to return 0 on systems where CPU 0 is not on Node 0. This leads to a kernel panic in slab.c. I've tested the patch below on a 16 processor x86_64 ES7000-600 server, and no longer see the panic I saw with the original 2.6.16-rc3. Signed-off-by: Dan Yeisley Acked-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 6ef9f9a..22e51be 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c @@ -351,7 +351,7 @@ void __init init_cpu_to_node(void) continue; if (apicid_to_node[apicid] == NUMA_NO_NODE) continue; - cpu_to_node[i] = apicid_to_node[apicid]; + numa_set_node(i,apicid_to_node[apicid]); } } -- cgit v0.10.2 From c8adb494a6df6b2be8e50a8dafd5bab231df3505 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 15 Feb 2006 15:17:42 -0800 Subject: [PATCH] swsusp: nuke noisy message I get about 88 squillion of these when suspending an old ad450nx server. Cc: Pavel Roskin Cc: "Rafael J. Wysocki" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 41f6636..8d5a598 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -91,10 +91,8 @@ static int save_highmem_zone(struct zone *zone) * corrected eventually when the cases giving rise to this * are better understood. */ - if (PageReserved(page)) { - printk("highmem reserved page?!\n"); + if (PageReserved(page)) continue; - } BUG_ON(PageNosave(page)); if (PageNosaveFree(page)) continue; -- cgit v0.10.2 From 61be6d660093edde709ed638c7e1c458bd88c941 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Feb 2006 15:17:43 -0800 Subject: [PATCH] mmconfig: add kernel parameter documentation Mention the "pci=nommconf" option in kernel-parameters.txt. Signed-off-by: Bjorn Helgaas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 8437036..ac75b57 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1133,6 +1133,8 @@ running once the system is up. Mechanism 1. conf2 [IA-32] Force use of PCI Configuration Mechanism 2. + nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI + Configuration nosort [IA-32] Don't sort PCI devices according to order given by the PCI BIOS. This sorting is done to get a device order compatible with -- cgit v0.10.2 From 7bbb79403163e047c6e333ff169db34e3c969e65 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 16 Feb 2006 11:08:09 +0000 Subject: [ARM] Fix SMP initialisation oops A change to the SMP initialisation caused the following oops: CPU1: Booted secondary processor CPU1: D VIPT write-back cache CPU1: I cache: 32768 bytes, associativity 4, 32 byte lines, 256 sets CPU1: D cache: 32768 bytes, associativity 4, 32 byte lines, 256 sets <7>Calibrating delay loop... 83.14 BogoMIPS (lpj=415744) <1>Unable to handle kernel NULL pointer dereference at virtual address 0000001c ... PC is at enqueue_task+0x1c/0x64 LR is at activate_task+0xcc/0xe4 SMP initialisation now requires cpu_possible_map to be initialised in setup_arch(). Move this from smp_prepare_cpus() to smp_init_cpus() and call it from our setup_arch() if CONFIG_SMP is enabled. Signed-off-by: Russell King diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index c45d10d..68273b4 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -771,6 +772,10 @@ void __init setup_arch(char **cmdline_p) paging_init(&meminfo, mdesc); request_standard_resources(&meminfo, mdesc); +#ifdef CONFIG_SMP + smp_init_cpus(); +#endif + cpu_init(); /* diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7338948..02aa300 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -338,7 +338,6 @@ void __init smp_prepare_boot_cpu(void) per_cpu(cpu_data, cpu).idle = current; - cpu_set(cpu, cpu_possible_map); cpu_set(cpu, cpu_present_map); cpu_set(cpu, cpu_online_map); } diff --git a/arch/arm/mach-integrator/platsmp.c b/arch/arm/mach-integrator/platsmp.c index ea10bd8..1bc8534 100644 --- a/arch/arm/mach-integrator/platsmp.c +++ b/arch/arm/mach-integrator/platsmp.c @@ -140,6 +140,18 @@ static void __init poke_milo(void) mb(); } +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +void __init smp_init_cpus(void) +{ + unsigned int i, ncores = get_core_count(); + + for (i = 0; i < ncores; i++) + cpu_set(i, cpu_possible_map); +} + void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int ncores = get_core_count(); @@ -176,14 +188,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) max_cpus = ncores; /* - * Initialise the possible/present maps. - * cpu_possible_map describes the set of CPUs which may be present - * cpu_present_map describes the set of CPUs populated + * Initialise the present map, which describes the set of CPUs + * actually populated at the present time. */ - for (i = 0; i < max_cpus; i++) { - cpu_set(i, cpu_possible_map); + for (i = 0; i < max_cpus; i++) cpu_set(i, cpu_present_map); - } /* * Do we need any more CPUs? If so, then let them know where diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index a8fbd76d..b8484e1 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -143,6 +143,18 @@ static void __init poke_milo(void) mb(); } +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +void __init smp_init_cpus(void) +{ + unsigned int i, ncores = get_core_count(); + + for (i = 0; i < ncores; i++) + cpu_set(i, cpu_possible_map); +} + void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int ncores = get_core_count(); @@ -179,14 +191,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) local_timer_setup(cpu); /* - * Initialise the possible/present maps. - * cpu_possible_map describes the set of CPUs which may be present - * cpu_present_map describes the set of CPUs populated + * Initialise the present map, which describes the set of CPUs + * actually populated at the present time. */ - for (i = 0; i < max_cpus; i++) { - cpu_set(i, cpu_possible_map); + for (i = 0; i < max_cpus; i++) cpu_set(i, cpu_present_map); - } /* * Do we need any more CPUs? If so, then let them know where diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h index 5a72e50..fe45f7f 100644 --- a/include/asm-arm/smp.h +++ b/include/asm-arm/smp.h @@ -42,6 +42,11 @@ extern void show_ipi_list(struct seq_file *p); asmlinkage void do_IPI(struct pt_regs *regs); /* + * Setup the SMP cpu_possible_map + */ +extern void smp_init_cpus(void); + +/* * Move global data into per-processor storage. */ extern void smp_store_cpu_info(unsigned int cpuid); -- cgit v0.10.2 From 90f9dd8f72773152b69042debd6b9ed6d224703a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 16 Feb 2006 14:43:01 +1100 Subject: [PATCH] Fix over-zealous tag clearing in radix_tree_delete If a tag is set for a node being deleted from a radix_tree, then that tag gets cleared from the parent of the node, even if it is set for some siblings of the node begin deleted. This patch changes the logic to include a test for any_tag_set similar to the logic a little futher down. Care is taken to ensure that 'nr_cleared_tags' remains equals to the number of entries in the 'tags' array which are set to '0' (which means that this tag is not set in the tree below pathp->node, and should be cleared at pathp->node and possibly above. [ Nick says: "Linus FYI, I was able to modify the radix tree test harness to catch the bug and can no longer trigger it after the fix. Resulting code passes all other harness tests as well of course." ] Signed-off-by: Neil Brown Acked-by: Nick Piggin Signed-off-by: Linus Torvalds diff --git a/lib/radix-tree.c b/lib/radix-tree.c index c0bd4a9..1e5b17d 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -752,12 +752,14 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) */ nr_cleared_tags = 0; for (tag = 0; tag < RADIX_TREE_TAGS; tag++) { + tags[tag] = 1; if (tag_get(pathp->node, tag, pathp->offset)) { tag_clear(pathp->node, tag, pathp->offset); - tags[tag] = 0; - nr_cleared_tags++; - } else - tags[tag] = 1; + if (!any_tag_set(pathp->node, tag)) { + tags[tag] = 0; + nr_cleared_tags++; + } + } } for (pathp--; nr_cleared_tags && pathp->node; pathp--) { -- cgit v0.10.2 From 0425a14213f373595bd23cacdc675f2b973a28d4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 16 Feb 2006 16:48:31 +0000 Subject: [MMC] mmci: allow small data transfers If a data transfer is small (less than a FIFO size) we would hang waiting for the data to be read due to the PIO interrupt not occuring. We allowed for this in our PIO interrupt handler, but not when setting up a data transfer. Apply the "fix" when setting up a data transfer as well. Signed-off-by: Russell King diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 37ee7f8..9fef29d 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -97,6 +97,13 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) { datactrl |= MCI_DPSM_DIRECTION; irqmask = MCI_RXFIFOHALFFULLMASK; + + /* + * If we have less than a FIFOSIZE of bytes to transfer, + * trigger a PIO interrupt as soon as any data is available. + */ + if (host->size < MCI_FIFOSIZE) + irqmask |= MCI_RXDATAAVLBLMASK; } else { /* * We don't actually need to include "FIFO empty" here -- cgit v0.10.2 From 6f6d75825dc49b082906b84537b4df28293c2977 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 15 Feb 2006 19:46:50 -0600 Subject: [IA64] Missing check for TIF_WORK if trace/audit enabled It appears that if auditing is enabled, the kernel fails to check for pending signals before returning to user mode. Signed-off-by: Jack Steiner Acked-by: Ken Chen Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 27b222c..930fdfc 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -569,7 +569,9 @@ GLOBAL_ENTRY(ia64_trace_syscall) .mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8 .mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10 br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value -.ret3: br.cond.sptk .work_pending_syscall_end +.ret3: +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk + br.cond.sptk .work_pending_syscall_end strace_error: ld8 r3=[r2] // load pt_regs.r8 -- cgit v0.10.2 From 898efface1a5076cbae5af87b935212b1869971b Mon Sep 17 00:00:00 2001 From: Kurt Hackel Date: Wed, 18 Jan 2006 17:01:25 -0800 Subject: [PATCH] ocfs2: recheck recovery state after getting lock * after successfully taking the $RECOVERY lock in EX mode, recheck to make sure that recovery has not already begun or completed on another node Signed-off-by: Kurt Hackel Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 186e9a7..f9ce864 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -2032,6 +2032,30 @@ again: dlm->reco.new_master); status = -EEXIST; } else { + status = 0; + + /* see if recovery was already finished elsewhere */ + spin_lock(&dlm->spinlock); + if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) { + status = -EINVAL; + mlog(0, "%s: got reco EX lock, but " + "node got recovered already\n", dlm->name); + if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM) { + mlog(ML_ERROR, "%s: new master is %u " + "but no dead node!\n", + dlm->name, dlm->reco.new_master); + BUG(); + } + } + spin_unlock(&dlm->spinlock); + } + + /* if this node has actually become the recovery master, + * set the master and send the messages to begin recovery */ + if (!status) { + mlog(0, "%s: dead=%u, this=%u, sending " + "begin_reco now\n", dlm->name, + dlm->reco.dead_node, dlm->node_num); status = dlm_send_begin_reco_message(dlm, dlm->reco.dead_node); /* this always succeeds */ -- cgit v0.10.2 From e2b5e4506f5c5187b91d7a79fbad28fe3ebd2fc5 Mon Sep 17 00:00:00 2001 From: Kurt Hackel Date: Wed, 18 Jan 2006 17:02:56 -0800 Subject: [PATCH] ocfs2: fix release of ast never reserved * fix a bug in dlm_convert_lock_handler where dlm_lockres_release_ast was being called even if no ast was ever reserved Signed-off-by: Kurt Hackel Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index 6001b22..f5c2f19 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c @@ -421,7 +421,7 @@ int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data) struct dlm_lockstatus *lksb; enum dlm_status status = DLM_NORMAL; u32 flags; - int call_ast = 0, kick_thread = 0; + int call_ast = 0, kick_thread = 0, ast_reserved = 0; if (!dlm_grab(dlm)) { dlm_error(DLM_REJECTED); @@ -490,6 +490,7 @@ int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data) status = __dlm_lockres_state_to_status(res); if (status == DLM_NORMAL) { __dlm_lockres_reserve_ast(res); + ast_reserved = 1; res->state |= DLM_LOCK_RES_IN_PROGRESS; status = __dlmconvert_master(dlm, res, lock, flags, cnv->requested_type, @@ -512,10 +513,10 @@ leave: else dlm_lock_put(lock); - /* either queue the ast or release it */ + /* either queue the ast or release it, if reserved */ if (call_ast) dlm_queue_ast(dlm, lock); - else + else if (ast_reserved) dlm_lockres_release_ast(dlm, res); if (kick_thread) -- cgit v0.10.2 From 44465a7daf7c4e34199b2b0ebb3c5101619dcb9d Mon Sep 17 00:00:00 2001 From: Kurt Hackel Date: Wed, 18 Jan 2006 17:05:38 -0800 Subject: [PATCH] ocfs2: add dlm_wait_for_node_death * add dlm_wait_for_node_death function to be used after receiving a network error. this will wait for the given timeout to allow the heartbeat callbacks to update the domain map. without this, some paths may spin and consume enough cpu that the heartbeat gets starved and never updates. Signed-off-by: Kurt Hackel Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 42eb53b..23ceaa7 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -208,6 +208,9 @@ static inline void __dlm_set_joining_node(struct dlm_ctxt *dlm, #define DLM_LOCK_RES_IN_PROGRESS 0x00000010 #define DLM_LOCK_RES_MIGRATING 0x00000020 +/* max milliseconds to wait to sync up a network failure with a node death */ +#define DLM_NODE_DEATH_WAIT_MAX (5 * 1000) + #define DLM_PURGE_INTERVAL_MS (8 * 1000) struct dlm_lock_resource @@ -658,6 +661,7 @@ int dlm_launch_recovery_thread(struct dlm_ctxt *dlm); void dlm_complete_recovery_thread(struct dlm_ctxt *dlm); void dlm_wait_for_recovery(struct dlm_ctxt *dlm); int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node); +int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout); void dlm_put(struct dlm_ctxt *dlm); struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm); diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index f5c2f19..f66e2d81 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c @@ -392,6 +392,11 @@ static enum dlm_status dlm_send_remote_convert_request(struct dlm_ctxt *dlm, } else { mlog_errno(tmpret); if (dlm_is_host_down(tmpret)) { + /* instead of logging the same network error over + * and over, sleep here and wait for the heartbeat + * to notice the node is dead. times out after 5s. */ + dlm_wait_for_node_death(dlm, res->owner, + DLM_NODE_DEATH_WAIT_MAX); ret = DLM_RECOVERING; mlog(0, "node %u died so returning DLM_RECOVERING " "from convert message!\n", res->owner); diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index d1a0038..e709412 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c @@ -646,7 +646,19 @@ retry_lock: mlog(0, "retrying lock with migration/" "recovery/in progress\n"); msleep(100); - dlm_wait_for_recovery(dlm); + /* no waiting for dlm_reco_thread */ + if (recovery) { + if (status == DLM_RECOVERING) { + mlog(0, "%s: got RECOVERING " + "for $REOCVERY lock, master " + "was %u\n", dlm->name, + res->owner); + dlm_wait_for_node_death(dlm, res->owner, + DLM_NODE_DEATH_WAIT_MAX); + } + } else { + dlm_wait_for_recovery(dlm); + } goto retry_lock; } diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index f9ce864..ed76bda 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -278,6 +278,24 @@ int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node) return dead; } +int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout) +{ + if (timeout) { + mlog(ML_NOTICE, "%s: waiting %dms for notification of " + "death of node %u\n", dlm->name, timeout, node); + wait_event_timeout(dlm->dlm_reco_thread_wq, + dlm_is_node_dead(dlm, node), + msecs_to_jiffies(timeout)); + } else { + mlog(ML_NOTICE, "%s: waiting indefinitely for notification " + "of death of node %u\n", dlm->name, node); + wait_event(dlm->dlm_reco_thread_wq, + dlm_is_node_dead(dlm, node)); + } + /* for now, return 0 */ + return 0; +} + /* callers of the top-level api calls (dlmlock/dlmunlock) should * block on the dlm->reco.event when recovery is in progress. * the dlm recovery thread will set this state when it begins -- cgit v0.10.2 From 558c70c59b75a5a53ba496fe3bccea80a9e3e6fb Mon Sep 17 00:00:00 2001 From: Kurt Hackel Date: Wed, 18 Jan 2006 17:07:47 -0800 Subject: [PATCH] ocfs2: manually grant remote recovery lock * fix a hang in recovery that occurred in dlmlock_remote. the $RECOVERY lock was never moved to the granted queue even after getting DLM_NORMAL back from the master node. Signed-off-by: Kurt Hackel Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index e709412..671d4ff 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c @@ -220,6 +220,17 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm, dlm_error(status); dlm_revert_pending_lock(res, lock); dlm_lock_put(lock); + } else if (dlm_is_recovery_lock(res->lockname.name, + res->lockname.len)) { + /* special case for the $RECOVERY lock. + * there will never be an AST delivered to put + * this lock on the proper secondary queue + * (granted), so do it manually. */ + mlog(0, "%s: $RECOVERY lock for this node (%u) is " + "mastered by %u; got lock, manually granting (no ast)\n", + dlm->name, dlm->node_num, res->owner); + list_del_init(&lock->list); + list_add_tail(&lock->list, &res->granted); } spin_unlock(&res->spinlock); -- cgit v0.10.2 From 745ae8ba29e729ec922393fa4d9448c385673599 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Thu, 9 Feb 2006 13:23:39 -0800 Subject: [PATCH] ocfs2: only checkpoint journal when asked to Disable automatic checkpointing of the journal - this is a relic from older ocfs2 days. Worth quite a bit of performance on longer running single node tests. Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index fa0bcac..d329c9d 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1584,10 +1584,9 @@ static int ocfs2_commit_thread(void *arg) while (!(kthread_should_stop() && atomic_read(&journal->j_num_trans) == 0)) { - wait_event_interruptible_timeout(osb->checkpoint_event, - atomic_read(&journal->j_num_trans) - || kthread_should_stop(), - OCFS2_CHECKPOINT_INTERVAL); + wait_event_interruptible(osb->checkpoint_event, + atomic_read(&journal->j_num_trans) + || kthread_should_stop()); status = ocfs2_commit_cache(osb); if (status < 0) diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 7d0a816..2f3a6ac 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h @@ -29,8 +29,6 @@ #include #include -#define OCFS2_CHECKPOINT_INTERVAL (8 * HZ) - enum ocfs2_journal_state { OCFS2_JOURNAL_FREE = 0, OCFS2_JOURNAL_LOADED, -- cgit v0.10.2 From f671c09bce88ea253d576c842f8f39d9a2a29028 Mon Sep 17 00:00:00 2001 From: Kurt Hackel Date: Tue, 14 Feb 2006 11:45:21 -0800 Subject: [PATCH] ocfs2: detach from heartbeat events before freeing mle Signed-off-by: Kurt Hackel Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index a3194fe..2e2e95e 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2482,7 +2482,9 @@ top: atomic_set(&mle->woken, 1); spin_unlock(&mle->spinlock); wake_up(&mle->wq); - /* final put will take care of list removal */ + /* do not need events any longer, so detach + * from heartbeat */ + __dlm_mle_detach_hb_events(dlm, mle); __dlm_put_mle(mle); } continue; @@ -2537,6 +2539,9 @@ top: spin_unlock(&res->spinlock); dlm_lockres_put(res); + /* about to get rid of mle, detach from heartbeat */ + __dlm_mle_detach_hb_events(dlm, mle); + /* dump the mle */ spin_lock(&dlm->master_lock); __dlm_put_mle(mle); -- cgit v0.10.2 From 10487fbd74f2f9c9b5fb2d77efd50eab48db191a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 16 Feb 2006 22:17:00 +0100 Subject: sis190: early setting of the pci driver private data Below this point, the error path will proceed through sis190_release_board(). It will happily oops if pci_set_drvdata() has not been issued. Signed-off-by: Francois Romieu diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index b420182..ed4bc91 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1791,6 +1791,8 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, goto out; } + pci_set_drvdata(pdev, dev); + tp = netdev_priv(dev); ioaddr = tp->mmio_addr; @@ -1827,8 +1829,6 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, if (rc < 0) goto err_remove_mii; - pci_set_drvdata(pdev, dev); - net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), " "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", pci_name(pdev), sis_chip_info[ent->driver_data].name, -- cgit v0.10.2 From 8f8b1138fc9f65e3591aac83a4ee394fef34ac1d Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Thu, 16 Feb 2006 14:01:48 -0800 Subject: [IA64] Count disabled cpus as potential hot-pluggable CPUs Minor updates to earlier patch. - Added to documentation to add ia64 as well. - Minor clarification on how to use disabled cpus - used plain max instead of max_t per Andew Morton. Signed-off-by: Ashok Raj Signed-off-by: Tony Luck diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 08c5d04..e052780 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -44,10 +44,20 @@ maxcpus=n Restrict boot time cpus to n. Say if you have 4 cpus, using maxcpus=2 will only boot 2. You can choose to bring the other cpus later online, read FAQ's for more info. -additional_cpus=n [x86_64 only] use this to limit hotpluggable cpus. - This option sets +additional_cpus*=n Use this to limit hotpluggable cpus. This option sets cpu_possible_map = cpu_present_map + additional_cpus +(*) Option valid only for following architectures +- x86_64, ia64 + +ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT +to determine the number of potentially hot-pluggable cpus. The implementation +should only rely on this to count the #of cpus, but *MUST* not rely on the +apicid values in those tables for disabled apics. In the event BIOS doesnt +mark such hot-pluggable cpus as disabled entries, one could use this +parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. + + CPU maps and such ----------------- [More on cpumaps and primitive to manipulate, please check diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 34795ed..ecd44bd 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -794,24 +794,21 @@ __init void prefill_possible_map(void) int possible, disabled_cpus; disabled_cpus = total_cpus - available_cpus; + if (additional_cpus == -1) { - if (disabled_cpus > 0) { - possible = total_cpus; + if (disabled_cpus > 0) additional_cpus = disabled_cpus; - } - else { - possible = available_cpus; + else additional_cpus = 0; - } - } else { - possible = available_cpus + additional_cpus; - } + } + + possible = available_cpus + additional_cpus; + if (possible > NR_CPUS) possible = NR_CPUS; printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", - possible, - max_t(int, additional_cpus, 0)); + possible, max((possible - available_cpus), 0)); for (i = 0; i < possible; i++) cpu_set(i, cpu_possible_map); -- cgit v0.10.2 From 3dfaf7a68e275a1a6bee4861fdd61f911e6eb7a2 Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Thu, 16 Feb 2006 22:36:12 +0000 Subject: [ARM] 3337/1: Fix NSLU2 flash support according to window size configuration patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch from Martin Michlmayr ARM patch 3226/1 (IXP4xx runtime expansion bus window size configuration) forgot to update mach-ixp4xx/nslu2-setup.c which leads to the following compilation error. Update NSLU2 flash support following patch 3226/1. CC arch/arm/mach-ixp4xx/nslu2-setup.o arch/arm/mach-ixp4xx/nslu2-setup.c:30: error: ‘NSLU2_FLASH_BASE’ undeclared here (not in a function) arch/arm/mach-ixp4xx/nslu2-setup.c:31: error: ‘NSLU2_FLASH_SIZE’ undeclared here (not in a function) make[1]: *** [arch/arm/mach-ixp4xx/nslu2-setup.o] Error 1 make: *** [arch/arm/mach-ixp4xx] Error 2 Signed-off-by: Martin Michlmayr --- nslu2-setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Signed-off-by: Russell King diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index da9340a..f260a9d 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -27,8 +27,6 @@ static struct flash_platform_data nslu2_flash_data = { }; static struct resource nslu2_flash_resource = { - .start = NSLU2_FLASH_BASE, - .end = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE, .flags = IORESOURCE_MEM, }; @@ -116,6 +114,10 @@ static void __init nslu2_init(void) { ixp4xx_sys_init(); + nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + nslu2_flash_resource.end = + IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; + pm_power_off = nslu2_power_off; platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices)); -- cgit v0.10.2 From 6c0fa49b18b09ba9e69c0999f89bc38fad95d8a6 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 16 Feb 2006 22:36:13 +0000 Subject: [ARM] 3338/1: old ABI compat: sys_socketcall Patch from Nicolas Pitre Commit 99595d0237926b5aba1fe4c844a011a1ba1ee1f8 forgot to intercept sys_socketcall as well. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 8c3035d..3173924 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -111,7 +111,7 @@ CALL(sys_statfs) /* 100 */ CALL(sys_fstatfs) CALL(sys_ni_syscall) - CALL(OBSOLETE(sys_socketcall)) + CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall))) CALL(sys_syslog) CALL(sys_setitimer) /* 105 */ CALL(sys_getitimer) diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index 9d4b764..8e2f9bc 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -64,6 +64,7 @@ * sys_connect: * sys_sendmsg: * sys_sendto: + * sys_socketcall: * * struct sockaddr_un loses its padding with EABI. Since the size of the * structure is used as a validation test in unix_mkname(), we need to @@ -78,6 +79,7 @@ #include #include #include +#include #include #include @@ -408,3 +410,31 @@ asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned fla return sys_sendmsg(fd, msg, flags); } +asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args) +{ + unsigned long r = -EFAULT, a[6]; + + switch (call) { + case SYS_BIND: + if (copy_from_user(a, args, 3 * sizeof(long)) == 0) + r = sys_oabi_bind(a[0], (struct sockaddr __user *)a[1], a[2]); + break; + case SYS_CONNECT: + if (copy_from_user(a, args, 3 * sizeof(long)) == 0) + r = sys_oabi_connect(a[0], (struct sockaddr __user *)a[1], a[2]); + break; + case SYS_SENDTO: + if (copy_from_user(a, args, 6 * sizeof(long)) == 0) + r = sys_oabi_sendto(a[0], (void __user *)a[1], a[2], a[3], + (struct sockaddr __user *)a[4], a[5]); + break; + case SYS_SENDMSG: + if (copy_from_user(a, args, 3 * sizeof(long)) == 0) + r = sys_oabi_sendmsg(a[0], (struct msghdr __user *)a[1], a[2]); + break; + default: + r = sys_socketcall(call, args); + } + + return r; +} -- cgit v0.10.2 From d9db950cfa3d674ee834d980c329efdf8e4a0568 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 16 Feb 2006 22:36:15 +0000 Subject: [ARM] 3339/1: ARM EABI: make unmuxed syscalls visible Patch from Nicolas Pitre With EABI the multiplex sys_ipc and sys_socketcall syscalls are unavailable and their support code even removed from the compiled kernel, and the new unmuxed syscalls must be used instead. Make those syscall numbers visible. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index 77430d6..8f331bb 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h @@ -309,7 +309,7 @@ #define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) #define __NR_waitid (__NR_SYSCALL_BASE+280) -#if 0 /* reserve these for un-muxing socketcall */ +#if defined(__ARM_EABI__) /* reserve these for un-muxing socketcall */ #define __NR_socket (__NR_SYSCALL_BASE+281) #define __NR_bind (__NR_SYSCALL_BASE+282) #define __NR_connect (__NR_SYSCALL_BASE+283) @@ -329,7 +329,7 @@ #define __NR_recvmsg (__NR_SYSCALL_BASE+297) #endif -#if 0 /* reserve these for un-muxing ipc */ +#if defined(__ARM_EABI__) /* reserve these for un-muxing ipc */ #define __NR_semop (__NR_SYSCALL_BASE+298) #define __NR_semget (__NR_SYSCALL_BASE+299) #define __NR_semctl (__NR_SYSCALL_BASE+300) @@ -347,7 +347,7 @@ #define __NR_request_key (__NR_SYSCALL_BASE+310) #define __NR_keyctl (__NR_SYSCALL_BASE+311) -#if 0 /* reserved for un-muxing ipc */ +#if defined(__ARM_EABI__) /* reserved for un-muxing ipc */ #define __NR_semtimedop (__NR_SYSCALL_BASE+312) #endif -- cgit v0.10.2 From 0d467502b7fc2656f01d7f18ab290c8d41762018 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 5 Feb 2006 17:52:21 -0500 Subject: [PATCH] wireless/atmel: fix setting TX key only in ENCODEEXT The previous patch that added ENCODEEXT and AUTH support to the atmel driver contained a slight error which would cause just setting the TX key index to also set the encryption key again. This patch allows any combination of setting the TX key index and setting an encryption key. Signed-off-by: Dan Williams Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 98a76f1..c1c27e1 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1872,7 +1872,7 @@ static int atmel_set_encodeext(struct net_device *dev, struct atmel_private *priv = netdev_priv(dev); struct iw_point *encoding = &wrqu->encoding; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int idx, key_len; + int idx, key_len, alg = ext->alg, set_key = 1; /* Determine and validate the key index */ idx = encoding->flags & IW_ENCODE_INDEX; @@ -1883,39 +1883,42 @@ static int atmel_set_encodeext(struct net_device *dev, } else idx = priv->default_key; - if ((encoding->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) { - priv->wep_is_on = 0; - priv->encryption_level = 0; - priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; - } + if (encoding->flags & IW_ENCODE_DISABLED) + alg = IW_ENCODE_ALG_NONE; - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { priv->default_key = idx; + set_key = ext->key_len > 0 ? 1 : 0; + } - /* Set the requested key */ - switch (ext->alg) { - case IW_ENCODE_ALG_NONE: - break; - case IW_ENCODE_ALG_WEP: - if (ext->key_len > 5) { - priv->wep_key_len[idx] = 13; - priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; - priv->encryption_level = 2; - } else if (ext->key_len > 0) { - priv->wep_key_len[idx] = 5; - priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; - priv->encryption_level = 1; - } else { + if (set_key) { + /* Set the requested key first */ + switch (alg) { + case IW_ENCODE_ALG_NONE: + priv->wep_is_on = 0; + priv->encryption_level = 0; + priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; + break; + case IW_ENCODE_ALG_WEP: + if (ext->key_len > 5) { + priv->wep_key_len[idx] = 13; + priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; + priv->encryption_level = 2; + } else if (ext->key_len > 0) { + priv->wep_key_len[idx] = 5; + priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; + priv->encryption_level = 1; + } else { + return -EINVAL; + } + priv->wep_is_on = 1; + memset(priv->wep_keys[idx], 0, 13); + key_len = min ((int)ext->key_len, priv->wep_key_len[idx]); + memcpy(priv->wep_keys[idx], ext->key, key_len); + break; + default: return -EINVAL; } - priv->wep_is_on = 1; - memset(priv->wep_keys[idx], 0, 13); - key_len = min ((int)ext->key_len, priv->wep_key_len[idx]); - memcpy(priv->wep_keys[idx], ext->key, key_len); - break; - default: - return -EINVAL; } return -EINPROGRESS; -- cgit v0.10.2 From 7345137930907ba747781636c60112f7c2789aa8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 5 Feb 2006 17:55:16 -0500 Subject: [PATCH] wireless/atmel: fix Open System authentication process bugs This patch fixes a number of bugs in the authentication process: 1) When falling back to Shared Key authentication mode from Open System, a missing 'return' would cause the auth request to be sent, but would drop the card into Management Error state. When falling back, the driver should also indicate that it is switching to Shared Key mode by setting exclude_unencrypted. 2) Initial authentication modes were apparently wrong in some cases, causing the driver to attempt Shared Key authentication mode when in fact the access point didn't support that mode or even had WEP disabled. The driver should set the correct initial authentication mode based on wep_is_on and exclude_unencrypted. 3) Authentication response packets from the access point in Open System mode were getting ignored because the driver was expecting the sequence number of a Shared Key mode response. The patch separates the OS and SK mode handling to provide the correct behavior. Signed-off-by: Dan Williams Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index c1c27e1..dfc2401 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -3064,17 +3064,26 @@ static void authenticate(struct atmel_private *priv, u16 frame_len) } if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { + int should_associate = 0; /* WEP */ if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum) return; - if (trans_seq_no == 0x0002 && - auth->el_id == C80211_MGMT_ElementID_ChallengeText) { - send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len); - return; + if (system == C80211_MGMT_AAN_OPENSYSTEM) { + if (trans_seq_no == 0x0002) { + should_associate = 1; + } + } else if (system == C80211_MGMT_AAN_SHAREDKEY) { + if (trans_seq_no == 0x0002 && + auth->el_id == C80211_MGMT_ElementID_ChallengeText) { + send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len); + return; + } else if (trans_seq_no == 0x0004) { + should_associate = 1; + } } - if (trans_seq_no == 0x0004) { + if (should_associate) { if(priv->station_was_associated) { atmel_enter_state(priv, STATION_STATE_REASSOCIATING); send_association_request(priv, 1); @@ -3087,11 +3096,13 @@ static void authenticate(struct atmel_private *priv, u16 frame_len) } } - if (status == C80211_MGMT_SC_AuthAlgNotSupported) { + if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { /* Do opensystem first, then try sharedkey */ - if (system == C80211_MGMT_AAN_OPENSYSTEM) { + if (system == WLAN_AUTH_OPEN) { priv->CurrentAuthentTransactionSeqNum = 0x001; - send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0); + priv->exclude_unencrypted = 1; + send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0); + return; } else if (priv->connect_to_any_BSS) { int bss_index; @@ -3442,10 +3453,13 @@ static void atmel_management_timer(u_long a) priv->AuthenticationRequestRetryCnt = 0; restart_search(priv); } else { + int auth = C80211_MGMT_AAN_OPENSYSTEM; priv->AuthenticationRequestRetryCnt++; priv->CurrentAuthentTransactionSeqNum = 0x0001; mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); - send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0); + if (priv->wep_is_on && priv->exclude_unencrypted) + auth = C80211_MGMT_AAN_SHAREDKEY; + send_authentication_request(priv, auth, NULL, 0); } break; @@ -3544,12 +3558,15 @@ static void atmel_command_irq(struct atmel_private *priv) priv->station_was_associated = priv->station_is_associated; atmel_enter_state(priv, STATION_STATE_READY); } else { + int auth = C80211_MGMT_AAN_OPENSYSTEM; priv->AuthenticationRequestRetryCnt = 0; atmel_enter_state(priv, STATION_STATE_AUTHENTICATING); mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); priv->CurrentAuthentTransactionSeqNum = 0x0001; - send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0); + if (priv->wep_is_on && priv->exclude_unencrypted) + auth = C80211_MGMT_AAN_SHAREDKEY; + send_authentication_request(priv, auth, NULL, 0); } return; } -- cgit v0.10.2 From e4444d1a3039354c388135073786efeb64d8ef0c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:41:52 +0100 Subject: [PATCH] x86_64: Update defconfig ... and enable 1394 by default. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 5683292..b337136 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc1-git2 -# Thu Jan 19 10:05:21 2006 +# Linux kernel version: 2.6.16-rc3 +# Mon Feb 13 22:31:24 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -21,7 +21,6 @@ CONFIG_DMI=y # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -267,6 +266,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -446,7 +446,6 @@ CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set CONFIG_BLK_DEV_PDC202XX_NEW=y -# CONFIG_PDC202XX_FORCE is not set # CONFIG_BLK_DEV_SVWKS is not set # CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set @@ -573,7 +572,33 @@ CONFIG_FUSION_MAX_SGE=128 # # IEEE 1394 (FireWire) support # -# CONFIG_IEEE1394 is not set +CONFIG_IEEE1394=y + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_IEEE1394_OUI_DB is not set +# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set +# CONFIG_IEEE1394_EXPORT_FULL_API is not set + +# +# Device Drivers +# + +# +# Texas Instruments PCILynx requires I2C +# +CONFIG_IEEE1394_OHCI1394=y + +# +# Protocol Drivers +# +# CONFIG_IEEE1394_VIDEO1394 is not set +# CONFIG_IEEE1394_SBP2 is not set +# CONFIG_IEEE1394_ETH1394 is not set +# CONFIG_IEEE1394_DV1394 is not set +CONFIG_IEEE1394_RAWIO=y # # I2O device support @@ -772,6 +797,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -871,6 +897,7 @@ CONFIG_HPET_MMAP=y # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_HDAPS is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -1101,7 +1128,6 @@ CONFIG_USB_MON=y # EDAC - error detection and reporting (RAS) # # CONFIG_EDAC is not set -# CONFIG_EDAC_POLL is not set # # Firmware Drivers @@ -1291,14 +1317,12 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_FRAME_POINTER is not set # CONFIG_FORCED_INLINING is not set -# CONFIG_UNWIND_INFO is not set # CONFIG_RCU_TORTURE_TEST is not set -CONFIG_INIT_DEBUG=y # CONFIG_DEBUG_RODATA is not set # CONFIG_IOMMU_DEBUG is not set -- cgit v0.10.2 From 99019e919969be88e7e4042f3afa296bd55ad9ec Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 16 Feb 2006 23:41:55 +0100 Subject: [PATCH] x86_64: make touch_nmi_watchdog() not touch impossible cpus' private data Along with that, also suppress the memory touching altogether when the watchdog is not running, to eliminate needless crosstalk. Plus ad a call to it to make things consistent (one could also consider removing the call in enable_timer_nmi_watchdog()). Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 8be407a..5bf17e4 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -236,6 +236,7 @@ static void enable_lapic_nmi_watchdog(void) { if (nmi_active < 0) { nmi_watchdog = NMI_LOCAL_APIC; + touch_nmi_watchdog(); setup_apic_nmi_watchdog(); } } @@ -456,15 +457,17 @@ static DEFINE_PER_CPU(int, nmi_touch); void touch_nmi_watchdog (void) { - int i; + if (nmi_watchdog > 0) { + unsigned cpu; - /* - * Tell other CPUs to reset their alert counters. We cannot - * do it ourselves because the alert count increase is not - * atomic. - */ - for (i = 0; i < NR_CPUS; i++) - per_cpu(nmi_touch, i) = 1; + /* + * Tell other CPUs to reset their alert counters. We cannot + * do it ourselves because the alert count increase is not + * atomic. + */ + for_each_present_cpu (cpu) + per_cpu(nmi_touch, cpu) = 1; + } touch_softlockup_watchdog(); } -- cgit v0.10.2 From a62eaf151d9cb478d127cfbc2e93c498869785b0 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:41:58 +0100 Subject: [PATCH] x86_64: Add boot option to disable randomized mappings and cleanup AMD SimNow!'s JIT doesn't like them at all in the guest. For distribution installation it's easiest if it's a boot time option. Also I moved the variable to a more appropiate place and make it independent from sysctl And marked __read_mostly which it is. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ac75b57..b874771 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1638,6 +1638,9 @@ running once the system is up. Format: ,,,,,[,[,[,]]] + norandmaps Don't use address space randomization + Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space + ______________________________________________________________________ Changelog: diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c index bdbeb77..7214c9b 100644 --- a/arch/i386/kernel/cpu/transmeta.c +++ b/arch/i386/kernel/cpu/transmeta.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b49affa..3b507bf 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -326,12 +326,6 @@ struct sysinfo { /* Force a compilation error if condition is true */ #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) -#ifdef CONFIG_SYSCTL -extern int randomize_va_space; -#else -#define randomize_va_space 1 -#endif - /* Trap pasters of __FUNCTION__ at compile-time */ #define __FUNCTION__ (__func__) diff --git a/include/linux/mm.h b/include/linux/mm.h index 75e9f07..26e1663 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1051,5 +1051,7 @@ int shrink_slab(unsigned long scanned, gfp_t gfp_mask, void drop_pagecache(void); void drop_slab(void); +extern int randomize_va_space; + #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 71dd6f6..7654d55 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -126,8 +126,6 @@ extern int sysctl_hz_timer; extern int acct_parm[]; #endif -int randomize_va_space = 1; - static int parse_table(int __user *, int, void __user *, size_t __user *, void __user *, size_t, ctl_table *, void **); static int proc_doutsstring(ctl_table *table, int write, struct file *filp, diff --git a/mm/memory.c b/mm/memory.c index 2bee1f2..9abc600 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -82,6 +82,16 @@ EXPORT_SYMBOL(num_physpages); EXPORT_SYMBOL(high_memory); EXPORT_SYMBOL(vmalloc_earlyreserve); +int randomize_va_space __read_mostly = 1; + +static int __init disable_randmaps(char *s) +{ + randomize_va_space = 0; + return 0; +} +__setup("norandmaps", disable_randmaps); + + /* * If a p?d_bad entry is found while walking page tables, report * the error, before resetting entry to p?d_none. Usually (but -- cgit v0.10.2 From 2391c4b594eb28abd58102de8f4e5d7a4fa39f4c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:42:01 +0100 Subject: [PATCH] x86_64: Don't call do_exit with interrupts disabled after IRET exception This caused a sigreturn with bad argument on a preemptible kernel to complain with Debug: sleeping function called from invalid context at /home/lsrc/quilt/linux/include/linux/rwsem.h:43 in_atomic():0, irqs_disabled():1 Call Trace: {__might_sleep+190} {profile_task_exit+21} {__do_exit+34} {do_wait+0} Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index b150c87..7c10e90 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -554,6 +554,7 @@ iret_label: /* running with kernel gs */ bad_iret: movq $-9999,%rdi /* better code? */ + sti jmp do_exit .previous -- cgit v0.10.2 From ab68805955ee3dd84a6aa76cd70e61fde996968d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:42:04 +0100 Subject: [PATCH] x86_64: Don't enable ATI apicmaintimer workaround when the machine has C2 or C3 Many laptops have problems with ticking the local APIC timer in C2/C3. The code added earlier to use it by default on ATI didn't really work for them. Don't enable it when the system supports C2/C3. This doesn't fix the problem fully, but at least it's not worse than before. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 4282d72..2585c1d 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -30,6 +30,9 @@ #include #include #include +#ifdef CONFIG_ACPI +#include +#endif #include #include @@ -260,6 +263,8 @@ __setup("apic", enable_ioapic_setup); And another hack to disable the IOMMU on VIA chipsets. + ... and others. Really should move this somewhere else. + Kludge-O-Rama. */ void __init check_ioapic(void) { @@ -307,6 +312,17 @@ void __init check_ioapic(void) case PCI_VENDOR_ID_ATI: if (apic_runs_main_timer != 0) break; +#ifdef CONFIG_ACPI + /* Don't do this for laptops right + right now because their timer + doesn't necessarily tick in C2/3 */ + if (acpi_fadt.revision >= 3 && + (acpi_fadt.plvl2_lat + acpi_fadt.plvl3_lat) < 1100) { + printk(KERN_INFO +"ATI board detected, but seems to be a laptop. Timer might be shakey, sorry\n"); + break; + } +#endif printk(KERN_INFO "ATI board detected. Using APIC/PM timer.\n"); apic_runs_main_timer = 1; -- cgit v0.10.2 From 7fd67843b96f90f59c9a244a1bc25137978a3ff9 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:42:07 +0100 Subject: [PATCH] x86_64: Disable tsc when apicpmtimer is active Otherwise it has no effect anyways. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 7a0a3e8..e5b14c5 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -1152,6 +1152,7 @@ __setup("noapicmaintimer", setup_noapicmaintimer); static __init int setup_apicpmtimer(char *s) { apic_calibrate_pmtmr = 1; + notsc_setup(NULL); return setup_apicmaintimer(NULL); } __setup("apicpmtimer", setup_apicpmtimer); diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 3c58c30..67841d1 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -1327,8 +1327,7 @@ static int __init nohpet_setup(char *s) __setup("nohpet", nohpet_setup); - -static int __init notsc_setup(char *s) +int __init notsc_setup(char *s) { notsc = 1; return 0; diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index c99832e..eca3f2d 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -133,6 +133,7 @@ extern int fix_aperture; extern int force_iommu; extern int reboot_force; +extern int notsc_setup(char *); extern void smp_local_timer_interrupt(struct pt_regs * regs); -- cgit v0.10.2 From 6574ffd74b03e35026f428a2c820e6ddf45d426c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:42:10 +0100 Subject: [PATCH] x86_64: Resolve the RIP of an early exception using kallsyms But do it after everything else to risk less from recursive crashes. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 692c737..02fc7fa 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -213,6 +213,11 @@ ENTRY(early_idt_handler) cmpl $2,early_recursion_flag(%rip) jz 1f call dump_stack +#ifdef CONFIG_KALLSYMS + leaq early_idt_ripmsg(%rip),%rdi + movq 8(%rsp),%rsi # get rip again + call __print_symbol +#endif 1: hlt jmp 1b early_recursion_flag: @@ -220,6 +225,8 @@ early_recursion_flag: early_idt_msg: .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n" +early_idt_ripmsg: + .asciz "RIP %s\n" .code32 ENTRY(no_long_mode) -- cgit v0.10.2 From fdb9df942437c6c5d1a6928d5fff824466c3af67 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:42:13 +0100 Subject: [PATCH] x86_64: Relax SRAT covers all memory check a bit Code was refusing good SRATs because about 12K got lost somewhere. Allow less than 1MB of difference before rejecting it. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index cd25300..809dc70 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c @@ -228,7 +228,8 @@ static int nodes_cover_memory(void) } e820ram = end_pfn - e820_hole_size(0, end_pfn); - if (pxmram < e820ram) { + /* We seem to lose 3 pages somewhere. Allow a bit of slack. */ + if ((long)(e820ram - pxmram) >= 1*1024*1024) { printk(KERN_ERR "SRAT: PXMs only cover %luMB of your %luMB e820 RAM. Not used.\n", (pxmram << PAGE_SHIFT) >> 20, -- cgit v0.10.2 From 2aed711a399cbc4a9bf239c13f05a8a8b460f215 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Feb 2006 23:42:16 +0100 Subject: [PATCH] x86_64: Always pass full number of nodes to NUMA hash computation Previously the numa hash code would be confused by holes in the node space and stop early. This is the first part of the fix for the non boot issue with empty nodes on Opterons. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c index a5663e0..dd60e71 100644 --- a/arch/x86_64/mm/k8topology.c +++ b/arch/x86_64/mm/k8topology.c @@ -155,7 +155,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) if (!found) return -1; - memnode_shift = compute_hash_shift(nodes, numnodes); + memnode_shift = compute_hash_shift(nodes, 8); if (memnode_shift < 0) { printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); return -1; diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 809dc70..482c257 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c @@ -271,7 +271,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) return -1; } - memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed)); + memnode_shift = compute_hash_shift(nodes, MAX_NUMNODES); if (memnode_shift < 0) { printk(KERN_ERR "SRAT: No NUMA node hash function found. Contact maintainer\n"); -- cgit v0.10.2 From dd942ae331425812930cd01766178b7e28e65f2d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 17 Feb 2006 01:39:16 +0100 Subject: [PATCH] Handle all and empty zones when setting up custom zonelists for mbind The memory allocator doesn't like empty zones (which have an uninitialized freelist), so a x86-64 system with a node fully in GFP_DMA32 only would crash on mbind. Fix that up by putting all possible zones as fallback into the zonelist and skipping the empty ones. In fact the code always enough allocated space for all zones, but only used it for the highest. This change just uses all the memory that was allocated before. This should work fine for now, but whoever implements node hot removal needs to fix this somewhere else too (or make sure zone datastructures by itself never go away, only their memory) Signed-off-by: Andi Kleen Acked-by: Christoph Lameter Signed-off-by: Linus Torvalds diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 3bd7fb7..323fdcf 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -132,19 +132,29 @@ static int mpol_check_policy(int mode, nodemask_t *nodes) } return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL; } + /* Generate a custom zonelist for the BIND policy. */ static struct zonelist *bind_zonelist(nodemask_t *nodes) { struct zonelist *zl; - int num, max, nd; + int num, max, nd, k; max = 1 + MAX_NR_ZONES * nodes_weight(*nodes); - zl = kmalloc(sizeof(void *) * max, GFP_KERNEL); + zl = kmalloc(sizeof(struct zone *) * max, GFP_KERNEL); if (!zl) return NULL; num = 0; - for_each_node_mask(nd, *nodes) - zl->zones[num++] = &NODE_DATA(nd)->node_zones[policy_zone]; + /* First put in the highest zones from all nodes, then all the next + lower zones etc. Avoid empty zones because the memory allocator + doesn't like them. If you implement node hot removal you + have to fix that. */ + for (k = policy_zone; k >= 0; k--) { + for_each_node_mask(nd, *nodes) { + struct zone *z = &NODE_DATA(nd)->node_zones[k]; + if (z->present_pages > 0) + zl->zones[num++] = z; + } + } zl->zones[num] = NULL; return zl; } -- cgit v0.10.2 From 726c14bf499e91e7ede4f1728830aba05c675061 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 17 Feb 2006 10:30:23 +1100 Subject: [PATCH] Provide an interface for getting the current tick length This provides an interface for arch code to find out how many nanoseconds are going to be added on to xtime by the next call to do_timer. The value returned is a fixed-point number in 52.12 format in nanoseconds. The reason for this format is that it gives the full precision that the timekeeping code is using internally. The motivation for this is to fix a problem that has arisen on 32-bit powerpc in that the value returned by do_gettimeofday drifts apart from xtime if NTP is being used. PowerPC is now using a lockless do_gettimeofday based on reading the timebase register and performing some simple arithmetic. (This method of getting the time is also exported to userspace via the VDSO.) However, the factor and offset it uses were calculated based on the nominal tick length and weren't being adjusted when NTP varied the tick length. Note that 64-bit powerpc has had the lockless do_gettimeofday for a long time now. It also had an extremely hairy routine that got called from the 32-bit compat routine for adjtimex, which adjusted the factor and offset according to what it thought the timekeeping code was going to do. Not only was this only called if a 32-bit task did adjtimex (i.e. not if a 64-bit task did adjtimex), it was also duplicating computations from kernel/timer.c and it wasn't clear that it was (still) correct. The simple solution is to ask the timekeeping code how long the current jiffy will be on each timer interrupt, after calling do_timer. If this jiffy will be a different length from the last one, we then need to compute new values for the factor and offset used in the lockless do_gettimeofday. In this way we can keep xtime and do_gettimeofday in sync, even when NTP is varying the tick length. Note that when adjtimex varies the tick length, it almost always introduces the variation from the next tick on. The only case I could see where adjtimex would vary the length of the current tick is when an old-style adjtime adjustment is being cancelled. (It's not clear to me why the adjustment has to be cancelled immediately rather than from the next tick on.) Thus I don't see any real need for a hook in adjtimex; the rare case of an old-style adjustment being cancelled can be fixed up at the next tick. Signed-off-by: Paul Mackerras Acked-by: john stultz Signed-off-by: Linus Torvalds diff --git a/include/linux/timex.h b/include/linux/timex.h index 04a4a8c..b7ca120 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -345,6 +345,9 @@ time_interpolator_reset(void) #endif /* !CONFIG_TIME_INTERPOLATION */ +/* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */ +extern u64 current_tick_length(void); + #endif /* KERNEL */ #endif /* LINUX_TIMEX_H */ diff --git a/kernel/timer.c b/kernel/timer.c index b9dad39..fe3a9a9 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -717,12 +717,16 @@ static void second_overflow(void) #endif } -/* in the NTP reference this is called "hardclock()" */ -static void update_wall_time_one_tick(void) +/* + * Returns how many microseconds we need to add to xtime this tick + * in doing an adjustment requested with adjtime. + */ +static long adjtime_adjustment(void) { - long time_adjust_step, delta_nsec; + long time_adjust_step; - if ((time_adjust_step = time_adjust) != 0 ) { + time_adjust_step = time_adjust; + if (time_adjust_step) { /* * We are doing an adjtime thing. Prepare time_adjust_step to * be within bounds. Note that a positive time_adjust means we @@ -733,10 +737,19 @@ static void update_wall_time_one_tick(void) */ time_adjust_step = min(time_adjust_step, (long)tickadj); time_adjust_step = max(time_adjust_step, (long)-tickadj); + } + return time_adjust_step; +} +/* in the NTP reference this is called "hardclock()" */ +static void update_wall_time_one_tick(void) +{ + long time_adjust_step, delta_nsec; + + time_adjust_step = adjtime_adjustment(); + if (time_adjust_step) /* Reduce by this step the amount of time left */ time_adjust -= time_adjust_step; - } delta_nsec = tick_nsec + time_adjust_step * 1000; /* * Advance the phase, once it gets to one microsecond, then @@ -759,6 +772,22 @@ static void update_wall_time_one_tick(void) } /* + * Return how long ticks are at the moment, that is, how much time + * update_wall_time_one_tick will add to xtime next time we call it + * (assuming no calls to do_adjtimex in the meantime). + * The return value is in fixed-point nanoseconds with SHIFT_SCALE-10 + * bits to the right of the binary point. + * This function has no side-effects. + */ +u64 current_tick_length(void) +{ + long delta_nsec; + + delta_nsec = tick_nsec + adjtime_adjustment() * 1000; + return ((u64) delta_nsec << (SHIFT_SCALE - 10)) + time_adj; +} + +/* * Using a loop looks inefficient, but "ticks" is * usually just one (we shouldn't be losing ticks, * we're doing this this way mainly for interrupt -- cgit v0.10.2 From d30864392823d5f38002fa32950689e651ee11da Mon Sep 17 00:00:00 2001 From: Joshua Kinard Date: Fri, 17 Feb 2006 03:52:25 +0000 Subject: [PATCH] Fix SGI O2 compile error in drivers/video/gbefb.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A sysfs function call uses the wrong parameter, and thus breaks a build on SGI O2. CC drivers/video/gbefb.o drivers/video/gbefb.c: In function ‘gbefb_remove’: drivers/video/gbefb.c:1246: error: ‘dev’ undeclared (first use in this function) drivers/video/gbefb.c:1246: error: (Each undeclared identifier is reported only once drivers/video/gbefb.c:1246: error: for each function it appears in.) make[2]: *** [drivers/video/gbefb.o] Error 1 Signed-off-by: Joshua Kinard Signed-off-by: Antonino Daplas Signed-off-by: Martin Michlmayr Signed-off-by: Linus Torvalds diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 38d2272..c9a7cdf 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -1243,7 +1243,7 @@ static int __devexit gbefb_remove(struct platform_device* p_dev) (void *)gbe_tiles.cpu, gbe_tiles.dma); release_mem_region(GBE_BASE, sizeof(struct sgi_gbe)); iounmap(gbe); - gbefb_remove_sysfs(dev); + gbefb_remove_sysfs(&p_dev->dev); framebuffer_release(info); return 0; -- cgit v0.10.2 From cfe91f9ce297e23e6fbdf61c02bdd8ab9af7c8a8 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert <76306.1226@compuserve.com> Date: Fri, 17 Feb 2006 03:16:55 -0500 Subject: [PATCH] i386: fix singlestepping though a syscall Do not mask TIF_SINGLESTEP bit in _TIF_WORK_MASK. Masking this stopped do_notify_resume() from being called when it should have been. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Linus Torvalds diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h index e20e995..1f7d48c 100644 --- a/include/asm-i386/thread_info.h +++ b/include/asm-i386/thread_info.h @@ -158,8 +158,8 @@ register unsigned long current_stack_pointer asm("esp") __attribute_used__; /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \ - (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|\ - _TIF_SECCOMP|_TIF_SYSCALL_EMU)) + (0x0000FFFF & ~(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ + _TIF_SECCOMP | _TIF_SYSCALL_EMU)) /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP) -- cgit v0.10.2 From aca0b510cdbf81d52e15014a720be2b8dfd26aea Mon Sep 17 00:00:00 2001 From: Jean Tourrilhes Date: Thu, 16 Feb 2006 17:44:54 -0800 Subject: [PATCH] Wavelan_cs bitfield fixes Some bitfields were incorrectly initialised in wavelan_cs, causing some compiler warning. Also killed a error message that should not be there... Signed-off-by: Jean Tourrilhes Signed-off-by: Jeff Garzik diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index cf37362..98122f3 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -950,16 +950,8 @@ wv_82593_cmd(struct net_device * dev, static inline int wv_diag(struct net_device * dev) { - int ret = FALSE; - - if(wv_82593_cmd(dev, "wv_diag(): diagnose", - OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED)) - ret = TRUE; - -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n"); -#endif - return(ret); + return(wv_82593_cmd(dev, "wv_diag(): diagnose", + OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED)); } /* wv_diag */ /*------------------------------------------------------------------*/ @@ -3604,8 +3596,8 @@ wv_82593_config(struct net_device * dev) cfblk.lin_prio = 0; /* conform to 802.3 backoff algoritm */ cfblk.exp_prio = 5; /* conform to 802.3 backoff algoritm */ cfblk.bof_met = 1; /* conform to 802.3 backoff algoritm */ - cfblk.ifrm_spc = 0x20; /* 32 bit times interframe spacing */ - cfblk.slottim_low = 0x20; /* 32 bit times slot time */ + cfblk.ifrm_spc = 0x20 >> 4; /* 32 bit times interframe spacing */ + cfblk.slottim_low = 0x20 >> 5; /* 32 bit times slot time */ cfblk.slottim_hi = 0x0; cfblk.max_retr = 15; cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE); /* Promiscuous mode */ -- cgit v0.10.2 From 56c8f7e290a1b3249c6a5b464fada8a167f2e5ff Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 13 Feb 2006 15:49:55 -0800 Subject: [PATCH] sk98lin: no d-link support (kconfig) The sk98lin driver was changed a while ago to remove support for the D-Link 530T card because that hardware has no working VPD data. The help text for Kconfig was not updated. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 47c72a6..ae8037a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2082,7 +2082,6 @@ config SK98LIN - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter - Allied Telesyn AT-2971T Gigabit Ethernet Adapter - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 - - DGE-530T Gigabit Ethernet Adapter - EG1032 v2 Instant Gigabit Network Adapter - EG1064 v2 Instant Gigabit Network Adapter - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) -- cgit v0.10.2 From 7a160c735a264de400cbbf4cf0fb3250007ae0c6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 13 Feb 2006 15:48:08 -0800 Subject: [PATCH] skge: no longer experimental Take the experimental dependency of skge driver, it is as stable as the others. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ae8037a..e45a8f9 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2020,8 +2020,8 @@ config SIS190 will be called sis190. This is recommended. config SKGE - tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL + tristate "New SysKonnect GigaEthernet support" + depends on PCI select CRC32 ---help--- This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx -- cgit v0.10.2 From 564f9abb34c936e5d0c7682129042dad14dbbb95 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 13 Feb 2006 15:46:48 -0800 Subject: [PATCH] skge: speed setting This is a clone of John Linville's fixed for speed setting on sky2 driver. The skge driver has the same code (and bug). It would not allow manually forcing 100 and 10 mbit. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/skge.c b/drivers/net/skge.c index bf55a4c..67fb19b 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -1697,6 +1697,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + if (skge->autoneg == AUTONEG_DISABLE) { reg = GM_GPCR_AU_ALL_DIS; gma_write16(hw, port, GM_GP_CTRL, @@ -1704,16 +1705,23 @@ static void yukon_mac_init(struct skge_hw *hw, int port) switch (skge->speed) { case SPEED_1000: + reg &= ~GM_GPCR_SPEED_100; reg |= GM_GPCR_SPEED_1000; - /* fallthru */ + break; case SPEED_100: + reg &= ~GM_GPCR_SPEED_1000; reg |= GM_GPCR_SPEED_100; + break; + case SPEED_10: + reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); + break; } if (skge->duplex == DUPLEX_FULL) reg |= GM_GPCR_DUP_FULL; } else reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; + switch (skge->flow_control) { case FLOW_MODE_NONE: skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); -- cgit v0.10.2 From 6f4c56b2ae10b680be518cc99f5308fc59236db2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 10 Feb 2006 15:58:59 -0800 Subject: [PATCH] sky2: speed setting fix Users report problems w/ auto-negotiation disabled and the link set to 100/Half or 10/Half. Problems range from poor performance to no link at all. The current sky2 code does not set things properly on link up if autonegotiation is disabled. Plus it does not contemplate a 10Mbit setting at all. This patch corrects that. Signed-off-by: John W. Linville Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index cae2edf..bfeba5b 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -520,10 +520,16 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) switch (sky2->speed) { case SPEED_1000: + reg &= ~GM_GPCR_SPEED_100; reg |= GM_GPCR_SPEED_1000; - /* fallthru */ + break; case SPEED_100: + reg &= ~GM_GPCR_SPEED_1000; reg |= GM_GPCR_SPEED_100; + break; + case SPEED_10: + reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); + break; } if (sky2->duplex == DUPLEX_FULL) @@ -1446,6 +1452,29 @@ static void sky2_link_up(struct sky2_port *sky2) sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); reg = gma_read16(hw, port, GM_GP_CTRL); + if (sky2->autoneg == AUTONEG_DISABLE) { + reg |= GM_GPCR_AU_ALL_DIS; + + /* Is write/read necessary? Copied from sky2_mac_init */ + gma_write16(hw, port, GM_GP_CTRL, reg); + gma_read16(hw, port, GM_GP_CTRL); + + switch (sky2->speed) { + case SPEED_1000: + reg &= ~GM_GPCR_SPEED_100; + reg |= GM_GPCR_SPEED_1000; + break; + case SPEED_100: + reg &= ~GM_GPCR_SPEED_1000; + reg |= GM_GPCR_SPEED_100; + break; + case SPEED_10: + reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); + break; + } + } else + reg &= ~GM_GPCR_AU_ALL_DIS; + if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) reg |= GM_GPCR_DUP_FULL; -- cgit v0.10.2 From ca5b0ec8ae9f11c85d1f27b19f182a054303f324 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 10 Feb 2006 02:00:43 -0800 Subject: [PATCH] smctr warning fix drivers/net/tokenring/smctr.c: In function `smctr_load_firmware': drivers/net/tokenring/smctr.c:2981: warning: assignment discards qualifiers from pointer target type Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h index b306c7e..88dfa2e 100644 --- a/drivers/net/tokenring/smctr.h +++ b/drivers/net/tokenring/smctr.h @@ -1042,7 +1042,7 @@ typedef struct net_local { __u16 functional_address[2]; __u16 bitwise_group_address[2]; - __u8 *ptr_ucode; + const __u8 *ptr_ucode; __u8 cleanup; -- cgit v0.10.2 From 0d613a27cc753bfacd20e6eaa2183bb7fef4c76e Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Tue, 7 Feb 2006 17:04:36 +0100 Subject: [PATCH] s390: lcs performance enhancements [patch 1/2] s390: lcs performance enhancements From: Klaus Wacker - When flood pinging (with large packet size) an LCS device, about 90 % of all packets are dropped by driver. - increased number of lcs IO buffers to 32. - use netif_stop_queue/netif_wake_queue in lcs_start_xmit routine - don't lock the whole xmit routine but just the piece of code where tx_buffer is touched. Signed-off-by: Frank Pavlic diffstat: lcs.c | 31 +++++++++++++++++-------------- lcs.h | 2 +- 2 files changed, 18 insertions(+), 15 deletions(-) Signed-off-by: Jeff Garzik diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 6229ba4..9cf88d7 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -98,9 +98,9 @@ lcs_register_debug_facility(void) return -ENOMEM; } debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view); - debug_set_level(lcs_dbf_setup, 4); + debug_set_level(lcs_dbf_setup, 2); debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view); - debug_set_level(lcs_dbf_trace, 4); + debug_set_level(lcs_dbf_trace, 2); return 0; } @@ -1292,9 +1292,8 @@ lcs_set_multicast_list(struct net_device *dev) LCS_DBF_TEXT(4, trace, "setmulti"); card = (struct lcs_card *) dev->priv; - if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) { + if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) schedule_work(&card->kernel_thread_starter); - } } #endif /* CONFIG_IP_MULTICAST */ @@ -1459,6 +1458,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) lcs_release_buffer(channel, buffer); card = (struct lcs_card *) ((char *) channel - offsetof(struct lcs_card, write)); + if (netif_queue_stopped(card->dev)) + netif_wake_queue(card->dev); spin_lock(&card->lock); card->tx_emitted--; if (card->tx_emitted <= 0 && card->tx_buffer != NULL) @@ -1478,6 +1479,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, struct net_device *dev) { struct lcs_header *header; + int rc = 0; LCS_DBF_TEXT(5, trace, "hardxmit"); if (skb == NULL) { @@ -1492,10 +1494,8 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, card->stats.tx_carrier_errors++; return 0; } - if (netif_queue_stopped(dev) ) { - card->stats.tx_dropped++; - return -EBUSY; - } + netif_stop_queue(card->dev); + spin_lock(&card->lock); if (card->tx_buffer != NULL && card->tx_buffer->count + sizeof(struct lcs_header) + skb->len + sizeof(u16) > LCS_IOBUFFERSIZE) @@ -1506,7 +1506,8 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, card->tx_buffer = lcs_get_buffer(&card->write); if (card->tx_buffer == NULL) { card->stats.tx_dropped++; - return -EBUSY; + rc = -EBUSY; + goto out; } card->tx_buffer->callback = lcs_txbuffer_cb; card->tx_buffer->count = 0; @@ -1518,13 +1519,18 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, header->type = card->lan_type; header->slot = card->portno; memcpy(header + 1, skb->data, skb->len); + spin_unlock(&card->lock); card->stats.tx_bytes += skb->len; card->stats.tx_packets++; dev_kfree_skb(skb); - if (card->tx_emitted <= 0) + netif_wake_queue(card->dev); + spin_lock(&card->lock); + if (card->tx_emitted <= 0 && card->tx_buffer != NULL) /* If this is the first tx buffer emit it immediately. */ __lcs_emit_txbuffer(card); - return 0; +out: + spin_unlock(&card->lock); + return rc; } static int @@ -1535,9 +1541,7 @@ lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) LCS_DBF_TEXT(5, trace, "pktxmit"); card = (struct lcs_card *) dev->priv; - spin_lock(&card->lock); rc = __lcs_start_xmit(card, skb, dev); - spin_unlock(&card->lock); return rc; } @@ -2319,7 +2323,6 @@ __init lcs_init_module(void) PRINT_ERR("Initialization failed\n"); return rc; } - return 0; } diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h index 08e60ad..2fad5e4 100644 --- a/drivers/s390/net/lcs.h +++ b/drivers/s390/net/lcs.h @@ -95,7 +95,7 @@ do { \ */ #define LCS_ILLEGAL_OFFSET 0xffff #define LCS_IOBUFFERSIZE 0x5000 -#define LCS_NUM_BUFFS 8 /* needs to be power of 2 */ +#define LCS_NUM_BUFFS 32 /* needs to be power of 2 */ #define LCS_MAC_LENGTH 6 #define LCS_INVALID_PORT_NO -1 #define LCS_LANCMD_TIMEOUT_DEFAULT 5 -- cgit v0.10.2 From 66cc5d5aee1ea427b3aeacdabd006a4195c81eee Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Tue, 7 Feb 2006 17:04:38 +0100 Subject: [PATCH] s390: some qeth driver fixes [patch 2/2] s390: some qeth driver fixes From: Frank Pavlic - fixed kernel panic when using EDDP support in Layer 2 mode - NULL pointer exception in qeth_set_offline fixed. - setting EDDP in Layer 2 mode did not set NETIF_F_(SG/TSO) flags when device became online. - use sscanf for parsing and converting IPv4 addresses from string to __u8 values. - qeth_string_to_ipaddr6 fixed. in case of double colon the converted IPv6 address out from the string was not correct in previous implementation. Signed-off-by: Frank Pavlic diffstat: qeth.h | 112 +++++++++++++++++++++++++----------------------------------- qeth_eddp.c | 11 ++++- qeth_main.c | 17 +++------ 3 files changed, 63 insertions(+), 77 deletions(-) Signed-off-by: Jeff Garzik diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 9a064d4..4df0fcd 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -1076,16 +1076,6 @@ qeth_get_qdio_q_format(struct qeth_card *card) } static inline int -qeth_isdigit(char * buf) -{ - while (*buf) { - if (!isdigit(*buf++)) - return 0; - } - return 1; -} - -static inline int qeth_isxdigit(char * buf) { while (*buf) { @@ -1104,33 +1094,17 @@ qeth_ipaddr4_to_string(const __u8 *addr, char *buf) static inline int qeth_string_to_ipaddr4(const char *buf, __u8 *addr) { - const char *start, *end; - char abuf[4]; - char *tmp; - int len; - int i; - - start = buf; - for (i = 0; i < 4; i++) { - if (i == 3) { - end = strchr(start,0xa); - if (end) - len = end - start; - else - len = strlen(start); - } - else { - end = strchr(start, '.'); - len = end - start; - } - if ((len <= 0) || (len > 3)) - return -EINVAL; - memset(abuf, 0, 4); - strncpy(abuf, start, len); - if (!qeth_isdigit(abuf)) + int count = 0, rc = 0; + int in[4]; + + rc = sscanf(buf, "%d.%d.%d.%d%n", + &in[0], &in[1], &in[2], &in[3], &count); + if (rc != 4 || count) + return -EINVAL; + for (count = 0; count < 4; count++) { + if (in[count] > 255) return -EINVAL; - addr[i] = simple_strtoul(abuf, &tmp, 10); - start = end + 1; + addr[count] = in[count]; } return 0; } @@ -1149,36 +1123,44 @@ qeth_ipaddr6_to_string(const __u8 *addr, char *buf) static inline int qeth_string_to_ipaddr6(const char *buf, __u8 *addr) { - const char *start, *end; - u16 *tmp_addr; - char abuf[5]; - char *tmp; - int len; - int i; - - tmp_addr = (u16 *)addr; - start = buf; - for (i = 0; i < 8; i++) { - if (i == 7) { - end = strchr(start,0xa); - if (end) - len = end - start; - else - len = strlen(start); - } - else { - end = strchr(start, ':'); - len = end - start; + char *end, *start; + __u16 *in; + char num[5]; + int num2, cnt, out, found, save_cnt; + unsigned short in_tmp[8] = {0, }; + + cnt = out = found = save_cnt = num2 = 0; + end = start = (char *) buf; + in = (__u16 *) addr; + memset(in, 0, 16); + while (end) { + end = strchr(end,':'); + if (end == NULL) { + end = (char *)buf + (strlen(buf)); + out = 1; + } + if ((end - start)) { + memset(num, 0, 5); + memcpy(num, start, end - start); + if (!qeth_isxdigit(num)) + return -EINVAL; + sscanf(start, "%x", &num2); + if (found) + in_tmp[save_cnt++] = num2; + else + in[cnt++] = num2; + if (out) + break; + } else { + if (found) + return -EINVAL; + found = 1; } - if ((len <= 0) || (len > 4)) - return -EINVAL; - memset(abuf, 0, 5); - strncpy(abuf, start, len); - if (!qeth_isxdigit(abuf)) - return -EINVAL; - tmp_addr[i] = simple_strtoul(abuf, &tmp, 16); - start = end + 1; - } + start = ++end; + } + cnt = 7; + while (save_cnt) + in[cnt--] = in_tmp[--save_cnt]; return 0; } diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index b023131..82cb4af 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c @@ -59,8 +59,7 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx) for (i = 0; i < ctx->num_pages; ++i) free_page((unsigned long)ctx->pages[i]); kfree(ctx->pages); - if (ctx->elements != NULL) - kfree(ctx->elements); + kfree(ctx->elements); kfree(ctx); } @@ -413,6 +412,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, QETH_DBF_TEXT(trace, 5, "eddpftcp"); eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; + if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { + eddp->skb_offset += sizeof(struct ethhdr); +#ifdef CONFIG_QETH_VLAN + if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) + eddp->skb_offset += VLAN_HLEN; +#endif /* CONFIG_QETH_VLAN */ + } tcph = eddp->skb->h.th; while (eddp->skb_offset < eddp->skb->len) { data_len = min((int)skb_shinfo(eddp->skb)->tso_size, @@ -483,6 +489,7 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, return -ENOMEM; } if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { + skb->mac.raw = (skb->data) + sizeof(struct qeth_hdr); memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN); #ifdef CONFIG_QETH_VLAN if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) { diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 410abea..dba7f7f 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -516,7 +516,8 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) QETH_DBF_TEXT(setup, 3, "setoffl"); QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); - netif_carrier_off(card->dev); + if (card->dev && netif_carrier_ok(card->dev)) + netif_carrier_off(card->dev); recover_flag = card->state; if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ PRINT_WARN("Stopping card %s interrupted by user!\n", @@ -1679,6 +1680,7 @@ qeth_cmd_timeout(unsigned long data) spin_unlock_irqrestore(&reply->card->lock, flags); } + static struct qeth_ipa_cmd * qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) { @@ -1699,7 +1701,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) QETH_CARD_IFNAME(card), card->info.chpid); card->lan_online = 0; - netif_carrier_off(card->dev); + if (card->dev && netif_carrier_ok(card->dev)) + netif_carrier_off(card->dev); return NULL; case IPA_CMD_STARTLAN: PRINT_INFO("Link reestablished on %s " @@ -5562,7 +5565,7 @@ qeth_set_multicast_list(struct net_device *dev) if (card->info.type == QETH_CARD_TYPE_OSN) return ; - QETH_DBF_TEXT(trace,3,"setmulti"); + QETH_DBF_TEXT(trace, 3, "setmulti"); qeth_delete_mc_addresses(card); if (card->options.layer2) { qeth_layer2_add_multicast(card); @@ -5579,7 +5582,6 @@ out: return; if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0) schedule_work(&card->kernel_thread_starter); - } static int @@ -7452,6 +7454,7 @@ qeth_softsetup_card(struct qeth_card *card) card->lan_online = 1; if (card->info.type==QETH_CARD_TYPE_OSN) goto out; + qeth_set_large_send(card, card->options.large_send); if (card->options.layer2) { card->dev->features |= NETIF_F_HW_VLAN_FILTER | @@ -7468,12 +7471,6 @@ qeth_softsetup_card(struct qeth_card *card) #endif goto out; } - if ((card->options.large_send == QETH_LARGE_SEND_EDDP) || - (card->options.large_send == QETH_LARGE_SEND_TSO)) - card->dev->features |= NETIF_F_TSO | NETIF_F_SG; - else - card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); - if ((rc = qeth_setadapter_parms(card))) QETH_DBF_TEXT_(setup, 2, "2err%d", rc); if ((rc = qeth_start_ipassists(card))) -- cgit v0.10.2 From f5e2a7b22e7d7dfda8794906d0fddeaaa09bb944 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Tue, 7 Feb 2006 21:17:22 -0800 Subject: [PATCH] bonding: fix a locking bug in bond_release bond_release returns EINVAL without releasing the bond lock if the slave device is not being bonded by the bond. The following patch ensures that the lock is released in this case. Signed-off-by: Stephen J. Bevan Acked-by: Jay Vosburgh Signed-off-by: Jeff Garzik diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e0f51af..bcf9f17 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1581,6 +1581,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) printk(KERN_INFO DRV_NAME ": %s: %s not enslaved\n", bond_dev->name, slave_dev->name); + write_unlock_bh(&bond->lock); return -EINVAL; } -- cgit v0.10.2 From 4cf808eb443ead42777a0230b73aec0cee7fb298 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 17 Feb 2006 20:38:21 +0100 Subject: [PATCH] Handle holes in node mask in node fallback list setup Change the find_next_best_node algorithm to correctly skip over holes in the node online mask. Previously it would not handle missing nodes correctly and cause crashes at boot. [Written by Linus, tested by AK] Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 62c1225..208812b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1541,29 +1541,29 @@ static int __initdata node_load[MAX_NUMNODES]; */ static int __init find_next_best_node(int node, nodemask_t *used_node_mask) { - int i, n, val; + int n, val; int min_val = INT_MAX; int best_node = -1; - for_each_online_node(i) { - cpumask_t tmp; + /* Use the local node if we haven't already */ + if (!node_isset(node, *used_node_mask)) { + node_set(node, *used_node_mask); + return node; + } - /* Start from local node */ - n = (node+i) % num_online_nodes(); + for_each_online_node(n) { + cpumask_t tmp; /* Don't want a node to appear more than once */ if (node_isset(n, *used_node_mask)) continue; - /* Use the local node if we haven't already */ - if (!node_isset(node, *used_node_mask)) { - best_node = node; - break; - } - /* Use the distance array to find the distance */ val = node_distance(node, n); + /* Penalize nodes under us ("prefer the next node") */ + val += (n < node); + /* Give preference to headless and unused nodes */ tmp = node_to_cpumask(n); if (!cpus_empty(tmp)) -- cgit v0.10.2 From 2ae5b30ff08cee422c7f6388a759f743633c7542 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 14 Dec 2005 13:10:49 -0700 Subject: [PATCH] Necessary evil to get sata_vsc to initialize with Intel iq3124h hba * libata does not care about error interrupts, so handle them locally * the interrupts that are ignored only appear to happen at init time Signed-off-by: Dan Williams Signed-off-by: Jeff Garzik diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 2e2c3b7..e484e8d 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@ -81,6 +81,19 @@ /* Port stride */ #define VSC_SATA_PORT_OFFSET 0x200 +/* Error interrupt status bit offsets */ +#define VSC_SATA_INT_ERROR_E_OFFSET 2 +#define VSC_SATA_INT_ERROR_P_OFFSET 4 +#define VSC_SATA_INT_ERROR_T_OFFSET 5 +#define VSC_SATA_INT_ERROR_M_OFFSET 1 +#define is_vsc_sata_int_err(port_idx, int_status) \ + (int_status & ((1 << (VSC_SATA_INT_ERROR_E_OFFSET + (8 * port_idx))) | \ + (1 << (VSC_SATA_INT_ERROR_P_OFFSET + (8 * port_idx))) | \ + (1 << (VSC_SATA_INT_ERROR_T_OFFSET + (8 * port_idx))) | \ + (1 << (VSC_SATA_INT_ERROR_M_OFFSET + (8 * port_idx))) \ + )\ + ) + static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { @@ -201,13 +214,28 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct ata_port *ap; ap = host_set->ports[i]; + + if (is_vsc_sata_int_err(i, int_status)) { + u32 err_status; + printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); + err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0; + vsc_sata_scr_write(ap, SCR_ERROR, err_status); + handled++; + } + if (ap && !(ap->flags & (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.ctl & ATA_NIEN))) + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { handled += ata_host_intr(ap, qc); + } else { + printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); + ata_chk_status(ap); + handled++; + } + } } } -- cgit v0.10.2 From 0565c26de7b2c069add553106f210b3128b67785 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Mon, 13 Feb 2006 18:55:25 +0800 Subject: [PATCH] libata: minor fix for 2.6.16-rc3 - Fix the array index value in ata_rwcmd_protocol() for the added FUA commands. - Filter out ATAPI packet command error messages in ata_pio_error() Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 46c4cdb..7ddd5a6 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -614,7 +614,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc) } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) { /* Unable to use DMA due to host limitation */ tf->protocol = ATA_PROT_PIO; - index = dev->multi_count ? 0 : 4; + index = dev->multi_count ? 0 : 8; } else { tf->protocol = ATA_PROT_DMA; index = 16; @@ -3357,11 +3357,12 @@ static void ata_pio_error(struct ata_port *ap) { struct ata_queued_cmd *qc; - printk(KERN_WARNING "ata%u: PIO error\n", ap->id); - qc = ata_qc_from_tag(ap, ap->active_tag); assert(qc != NULL); + if (qc->tf.command != ATA_CMD_PACKET) + printk(KERN_WARNING "ata%u: PIO error\n", ap->id); + /* make sure qc->err_mask is available to * know what's wrong and recover */ -- cgit v0.10.2 From c15d85c8f3f73b5f20aae7928e25b6996f16b328 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 15 Feb 2006 15:59:25 +0100 Subject: [PATCH] Add missing FUA write to sata_mv dma command list Signed-off-by: Jens Axboe Signed-off-by: Jeff Garzik diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 6fddf17..2770005 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -997,6 +997,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) case ATA_CMD_READ_EXT: case ATA_CMD_WRITE: case ATA_CMD_WRITE_EXT: + case ATA_CMD_WRITE_FUA_EXT: mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0); break; #ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */ -- cgit v0.10.2 From b2f49033d80c952a0ffc2d5647bc1a0b8a09c1b3 Mon Sep 17 00:00:00 2001 From: Peter Staubach Date: Fri, 17 Feb 2006 13:52:36 -0800 Subject: [PATCH] fix deadlock in ext2 Fix a deadlock possible in the ext2 file system implementation. This deadlock occurs when a file is removed from an ext2 file system which was mounted with the "sync" mount option. The problem is that ext2_xattr_delete_inode() was invoking the routine, sync_dirty_buffer(), using a buffer head which was previously locked via lock_buffer(). The first thing that sync_dirty_buffer() does is to lock the buffer head that it was passed. It does this via lock_buffer(). Oops. The solution is to unlock the buffer head in ext2_xattr_delete_inode() before invoking sync_dirty_buffer(). This makes the code in ext2_xattr_delete_inode() obey the same locking rules as all other callers of sync_dirty_buffer() in the ext2 file system implementation. Signed-off-by: Peter Staubach Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index a2ca310..86ae8e9 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -792,18 +792,20 @@ ext2_xattr_delete_inode(struct inode *inode) ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1); get_bh(bh); bforget(bh); + unlock_buffer(bh); } else { HDR(bh)->h_refcount = cpu_to_le32( le32_to_cpu(HDR(bh)->h_refcount) - 1); if (ce) mb_cache_entry_release(ce); + ea_bdebug(bh, "refcount now=%d", + le32_to_cpu(HDR(bh)->h_refcount)); + unlock_buffer(bh); mark_buffer_dirty(bh); if (IS_SYNC(inode)) sync_dirty_buffer(bh); DQUOT_FREE_BLOCK(inode, 1); } - ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); - unlock_buffer(bh); EXT2_I(inode)->i_file_acl = 0; cleanup: -- cgit v0.10.2 From 8c9e877949d953e80d0d400bc4d1d1195a2028a4 Mon Sep 17 00:00:00 2001 From: Marcel Selhorst Date: Fri, 17 Feb 2006 13:52:41 -0800 Subject: [PATCH] Infineon TPM: IO-port leakage fix, WTX-bugfix Fix IO-port leakage from request_region in case of error during TPM initialization, adds more pnp-verification and fixes a WTX-bug. Signed-off-by: Marcel Selhorst Acked-by: Kylene Jo Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index ec75909..24095f6 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -33,6 +33,7 @@ static int TPM_INF_DATA; static int TPM_INF_ADDR; static int TPM_INF_BASE; +static int TPM_INF_ADDR_LEN; static int TPM_INF_PORT_LEN; /* TPM header definitions */ @@ -195,6 +196,7 @@ static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) int i; int ret; u32 size = 0; + number_of_wtx = 0; recv_begin: /* start receiving header */ @@ -378,24 +380,35 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { TPM_INF_ADDR = pnp_port_start(dev, 0); + TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); TPM_INF_DATA = (TPM_INF_ADDR + 1); TPM_INF_BASE = pnp_port_start(dev, 1); TPM_INF_PORT_LEN = pnp_port_len(dev, 1); - if (!TPM_INF_PORT_LEN) - return -EINVAL; + if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { + rc = -EINVAL; + goto err_last; + } dev_info(&dev->dev, "Found %s with ID %s\n", dev->name, dev_id->id); - if (!((TPM_INF_BASE >> 8) & 0xff)) - return -EINVAL; + if (!((TPM_INF_BASE >> 8) & 0xff)) { + rc = -EINVAL; + goto err_last; + } /* publish my base address and request region */ tpm_inf.base = TPM_INF_BASE; if (request_region (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { - release_region(tpm_inf.base, TPM_INF_PORT_LEN); - return -EINVAL; + rc = -EINVAL; + goto err_last; + } + if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN, + "tpm_infineon0") == NULL) { + rc = -EINVAL; + goto err_last; } } else { - return -EINVAL; + rc = -EINVAL; + goto err_last; } /* query chip for its vendor, its version number a.s.o. */ @@ -443,8 +456,8 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, dev_err(&dev->dev, "Could not set IO-ports to 0x%lx\n", tpm_inf.base); - release_region(tpm_inf.base, TPM_INF_PORT_LEN); - return -EIO; + rc = -EIO; + goto err_release_region; } /* activate register */ @@ -471,14 +484,21 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, rc = tpm_register_hardware(&dev->dev, &tpm_inf); if (rc < 0) { - release_region(tpm_inf.base, TPM_INF_PORT_LEN); - return -ENODEV; + rc = -ENODEV; + goto err_release_region; } return 0; } else { - dev_info(&dev->dev, "No Infineon TPM found!\n"); - return -ENODEV; + rc = -ENODEV; + goto err_release_region; } + +err_release_region: + release_region(tpm_inf.base, TPM_INF_PORT_LEN); + release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); + +err_last: + return rc; } static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) @@ -518,5 +538,5 @@ module_exit(cleanup_inf); MODULE_AUTHOR("Marcel Selhorst "); MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); -MODULE_VERSION("1.6"); +MODULE_VERSION("1.7"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 05efc67d100ff6c3364604b72729addf1a86fdab Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 17 Feb 2006 13:52:42 -0800 Subject: [PATCH] arch/sh/Kconfig: fix the ISA_DMA_API dependencies Jean-Luc Leger found this obvious typo. Signed-off-by: Adrian Bunk Acked-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 504d56f..e73621d 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -446,7 +446,7 @@ endmenu config ISA_DMA_API bool - depends on MPC1211 + depends on SH_MPC1211 default y menu "Kernel features" -- cgit v0.10.2 From 4bbf39c29bc3409d6454faf0dfa1b3b0aa2ac2af Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 17 Feb 2006 13:52:44 -0800 Subject: [PATCH] Introduce CONFIG_DEFAULT_MIGRATION_COST Heiko Carstens wrote: The boot sequence on s390 sometimes takes ages and we spend a very long time (up to one or two minutes) in calibrate_migration_costs. The time spent there differs from boot to boot. Also the calculated costs differ a lot. I've seen differences by up to a factor of 15 (yes, factor not percent). Also I doubt that making these measurements make much sense on a completely virtualized architecture where you cannot tell how much cpu time you will get anyway. So introduce the CONFIG_DEFAULT_MIGRATION_COST method for an architecture to set the scheduler migration costs. This turns off automatic detection of migration costs. Makes sense on virtual platforms, where migration costs are hard to measure accurately. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b66602a..b7ca5bf 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -80,6 +80,10 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config DEFAULT_MIGRATION_COST + int + default "1000000" + config MATHEMU bool "IEEE FPU emulation" depends on MARCH_G5 diff --git a/kernel/sched.c b/kernel/sched.c index 66d9572..12d291b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5058,7 +5058,18 @@ static void init_sched_build_groups(struct sched_group groups[], cpumask_t span, #define MAX_DOMAIN_DISTANCE 32 static unsigned long long migration_cost[MAX_DOMAIN_DISTANCE] = - { [ 0 ... MAX_DOMAIN_DISTANCE-1 ] = -1LL }; + { [ 0 ... MAX_DOMAIN_DISTANCE-1 ] = +/* + * Architectures may override the migration cost and thus avoid + * boot-time calibration. Unit is nanoseconds. Mostly useful for + * virtualized hardware: + */ +#ifdef CONFIG_DEFAULT_MIGRATION_COST + CONFIG_DEFAULT_MIGRATION_COST +#else + -1LL +#endif +}; /* * Allow override of migration cost - in units of microseconds. -- cgit v0.10.2 From 6d751c43b29deb1d990fb9644c13ca941c9d1305 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 17 Feb 2006 13:52:45 -0800 Subject: [PATCH] s390: ccw device disbanding If __ccw_device_disband_start() fails to initiate disbanding, it should finish with ccw_device_disband_done() (which leaves the device in offline state) instead of ccw_device_verify_done() (which leaves the device in online state). Signed-off-by: Cornelia Huck Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index d2a5b04..85b1020 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -405,7 +405,7 @@ __ccw_device_disband_start(struct ccw_device *cdev) cdev->private->iretry = 5; cdev->private->imask >>= 1; } - ccw_device_verify_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV); + ccw_device_disband_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV); } /* -- cgit v0.10.2 From 1fca251f36fac3fae7d9cf10de69c2c93f6c0000 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 17 Feb 2006 13:52:46 -0800 Subject: [PATCH] s390: fix preempt_count of idle thread with cpu hotplug Set preempt_count of idle_thread to zero before switching off cpu. Otherwise the preempt_count will be wrong if the cpu is switched on again since the thread will be reused. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 008c745..da6fbae 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -128,8 +128,10 @@ void default_idle(void) __ctl_set_bit(8, 15); #ifdef CONFIG_HOTPLUG_CPU - if (cpu_is_offline(cpu)) + if (cpu_is_offline(cpu)) { + preempt_enable_no_resched(); cpu_die(); + } #endif local_mcck_disable(); -- cgit v0.10.2 From 255acee706b333b79f593dd366f16e1f107cccc3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 17 Feb 2006 13:52:46 -0800 Subject: [PATCH] s390: additional_cpus parameter Introduce additional_cpus command line option. By default no additional cpu can be attached to the system anymore. Only the cpus present at IPL time can be switched on/off. If it is desired that additional cpus can be attached to the system the maximum number of additional cpus needs to be specified with this option. This change is necessary in order to limit the waste of per_cpu data structures. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index e052780..4d3355d 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -11,6 +11,8 @@ Joel Schopp ia64/x86_64: Ashok Raj + s390: + Heiko Carstens Authors: Ashok Raj Lots of feedback: Nathan Lynch , @@ -44,11 +46,9 @@ maxcpus=n Restrict boot time cpus to n. Say if you have 4 cpus, using maxcpus=2 will only boot 2. You can choose to bring the other cpus later online, read FAQ's for more info. -additional_cpus*=n Use this to limit hotpluggable cpus. This option sets - cpu_possible_map = cpu_present_map + additional_cpus - -(*) Option valid only for following architectures -- x86_64, ia64 +additional_cpus=n [x86_64, s390 only] use this to limit hotpluggable cpus. + This option sets + cpu_possible_map = cpu_present_map + additional_cpus ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT to determine the number of potentially hot-pluggable cpus. The implementation diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index de87842..24f62f1 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -600,6 +600,7 @@ setup_arch(char **cmdline_p) init_mm.brk = (unsigned long) &_end; parse_cmdline_early(cmdline_p); + parse_early_param(); setup_memory(); setup_resources(); @@ -607,6 +608,7 @@ setup_arch(char **cmdline_p) cpu_init(); __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; + smp_setup_cpu_possible_map(); /* * Create kernel page tables and switch to virtual addressing. diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 0d1ad5d..53291e9 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1,8 +1,7 @@ /* * arch/s390/kernel/smp.c * - * S390 version - * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) IBM Corp. 1999,2006 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * Martin Schwidefsky (schwidefsky@de.ibm.com) * Heiko Carstens (heiko.carstens@de.ibm.com) @@ -41,8 +40,6 @@ #include #include -/* prototypes */ - extern volatile int __cpu_logical_map[]; /* @@ -51,13 +48,11 @@ extern volatile int __cpu_logical_map[]; struct _lowcore *lowcore_ptr[NR_CPUS]; -cpumask_t cpu_online_map; -cpumask_t cpu_possible_map = CPU_MASK_ALL; +cpumask_t cpu_online_map = CPU_MASK_NONE; +cpumask_t cpu_possible_map = CPU_MASK_NONE; static struct task_struct *current_set[NR_CPUS]; -EXPORT_SYMBOL(cpu_online_map); - /* * Reboot, halt and power_off routines for SMP. */ @@ -490,10 +485,10 @@ void smp_ctl_clear_bit(int cr, int bit) { * Lets check how many CPUs we have. */ -void -__init smp_check_cpus(unsigned int max_cpus) +static unsigned int +__init smp_count_cpus(void) { - int cpu, num_cpus; + unsigned int cpu, num_cpus; __u16 boot_cpu_addr; /* @@ -503,19 +498,20 @@ __init smp_check_cpus(unsigned int max_cpus) boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; current_thread_info()->cpu = 0; num_cpus = 1; - for (cpu = 0; cpu <= 65535 && num_cpus < max_cpus; cpu++) { + for (cpu = 0; cpu <= 65535; cpu++) { if ((__u16) cpu == boot_cpu_addr) continue; - __cpu_logical_map[num_cpus] = (__u16) cpu; - if (signal_processor(num_cpus, sigp_sense) == + __cpu_logical_map[1] = (__u16) cpu; + if (signal_processor(1, sigp_sense) == sigp_not_operational) continue; - cpu_set(num_cpus, cpu_present_map); num_cpus++; } printk("Detected %d CPU's\n",(int) num_cpus); printk("Boot cpu address %2X\n", boot_cpu_addr); + + return num_cpus; } /* @@ -676,6 +672,32 @@ __cpu_up(unsigned int cpu) return 0; } +static unsigned int __initdata additional_cpus; + +void __init smp_setup_cpu_possible_map(void) +{ + unsigned int pcpus, cpu; + + pcpus = smp_count_cpus() + additional_cpus; + + if (pcpus > NR_CPUS) + pcpus = NR_CPUS; + + for (cpu = 0; cpu < pcpus; cpu++) + cpu_set(cpu, cpu_possible_map); + + cpu_present_map = cpu_possible_map; +} + +#ifdef CONFIG_HOTPLUG_CPU + +static int __init setup_additional_cpus(char *s) +{ + additional_cpus = simple_strtoul(s, NULL, 0); + return 0; +} +early_param("additional_cpus", setup_additional_cpus); + int __cpu_disable(void) { @@ -744,6 +766,8 @@ cpu_die(void) for(;;); } +#endif /* CONFIG_HOTPLUG_CPU */ + /* * Cycle through the processors and setup structures. */ @@ -757,7 +781,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* request the 0x1201 emergency signal external interrupt */ if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) panic("Couldn't request external interrupt 0x1201"); - smp_check_cpus(max_cpus); memset(lowcore_ptr,0,sizeof(lowcore_ptr)); /* * Initialize prefix pages and stacks for all possible cpus @@ -806,14 +829,12 @@ void __devinit smp_prepare_boot_cpu(void) BUG_ON(smp_processor_id() != 0); cpu_set(0, cpu_online_map); - cpu_set(0, cpu_present_map); S390_lowcore.percpu_offset = __per_cpu_offset[0]; current_set[0] = current; } void smp_cpus_done(unsigned int max_cpus) { - cpu_present_map = cpu_possible_map; } /* @@ -845,6 +866,7 @@ static int __init topology_init(void) subsys_initcall(topology_init); +EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_possible_map); EXPORT_SYMBOL(lowcore_ptr); EXPORT_SYMBOL(smp_ctl_set_bit); diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 9c6e9c3..444dae5 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h @@ -31,6 +31,7 @@ typedef struct __u16 cpu; } sigp_info; +extern void smp_setup_cpu_possible_map(void); extern int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic, int wait, int cpu); #define NO_PROC_ID 0xFF /* No processor magic marker */ @@ -104,6 +105,7 @@ smp_call_function_on(void (*func) (void *info), void *info, #define smp_cpu_not_running(cpu) 1 #define smp_get_cpu(cpu) ({ 0; }) #define smp_put_cpu(cpu) ({ 0; }) +#define smp_setup_cpu_possible_map() #endif #endif -- cgit v0.10.2 From 37a3302618a51520e2056494715ea6b4776dd8ab Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 17 Feb 2006 13:52:47 -0800 Subject: [PATCH] s390: possible_cpus parameter Introduce possible_cpus command line option. Hard sets the number of bits set in cpu_possible_map. Unlike the additional_cpus parameter this one guarantees that num_possible_cpus() will stay constant even if the system gets rebooted and a different number of cpus are present at startup. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 4d3355d..e71bc6c 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -58,6 +58,12 @@ mark such hot-pluggable cpus as disabled entries, one could use this parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. +possible_cpus=n [s390 only] use this to set hotpluggable cpus. + This option sets possible_cpus bits in + cpu_possible_map. Thus keeping the numbers of bits set + constant even if the machine gets rebooted. + This option overrides additional_cpus. + CPU maps and such ----------------- [More on cpumaps and primitive to manipulate, please check diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 53291e9..d0a2745 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -673,15 +673,16 @@ __cpu_up(unsigned int cpu) } static unsigned int __initdata additional_cpus; +static unsigned int __initdata possible_cpus; void __init smp_setup_cpu_possible_map(void) { unsigned int pcpus, cpu; - pcpus = smp_count_cpus() + additional_cpus; + pcpus = min(smp_count_cpus() + additional_cpus, (unsigned int) NR_CPUS); - if (pcpus > NR_CPUS) - pcpus = NR_CPUS; + if (possible_cpus) + pcpus = min(possible_cpus, (unsigned int) NR_CPUS); for (cpu = 0; cpu < pcpus; cpu++) cpu_set(cpu, cpu_possible_map); @@ -698,6 +699,13 @@ static int __init setup_additional_cpus(char *s) } early_param("additional_cpus", setup_additional_cpus); +static int __init setup_possible_cpus(char *s) +{ + possible_cpus = simple_strtoul(s, NULL, 0); + return 0; +} +early_param("possible_cpus", setup_possible_cpus); + int __cpu_disable(void) { -- cgit v0.10.2 From 54330456b2e3398743586254f6d7695061ea0d49 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 17 Feb 2006 13:52:48 -0800 Subject: [PATCH] s390: smp initialization speed The last changes that introduced the additional_cpus command line parameter also introduced a regression regarding smp initialization speed. In smp_setup_cpu_possible_map() cpu_present_map is set to the same value as cpu_possible_map. Especially that means that bits in the present map will be set for cpus that are not present. This will cause a slow down in the initial cpu_up() loop in smp_init() since trying to take cpus online that aren't present takes a while. Fix this by setting only bits for present cpus in cpu_present_map and set cpu_present_map to cpu_possible_map in smp_cpus_done(). Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index d0a2745..7dbe00c 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -677,17 +677,21 @@ static unsigned int __initdata possible_cpus; void __init smp_setup_cpu_possible_map(void) { - unsigned int pcpus, cpu; + unsigned int phy_cpus, pos_cpus, cpu; - pcpus = min(smp_count_cpus() + additional_cpus, (unsigned int) NR_CPUS); + phy_cpus = smp_count_cpus(); + pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); if (possible_cpus) - pcpus = min(possible_cpus, (unsigned int) NR_CPUS); + pos_cpus = min(possible_cpus, (unsigned int) NR_CPUS); - for (cpu = 0; cpu < pcpus; cpu++) + for (cpu = 0; cpu < pos_cpus; cpu++) cpu_set(cpu, cpu_possible_map); - cpu_present_map = cpu_possible_map; + phy_cpus = min(phy_cpus, pos_cpus); + + for (cpu = 0; cpu < phy_cpus; cpu++) + cpu_set(cpu, cpu_present_map); } #ifdef CONFIG_HOTPLUG_CPU @@ -843,6 +847,7 @@ void __devinit smp_prepare_boot_cpu(void) void smp_cpus_done(unsigned int max_cpus) { + cpu_present_map = cpu_possible_map; } /* -- cgit v0.10.2 From 6cadb78b3bec0a439a99db8fb550dc568e924ae6 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 17 Feb 2006 13:52:49 -0800 Subject: [PATCH] s390: fix assignment instead of check in ccw_device_set_online() Fix assignment instead of check in ccw_device_set_online(). Also remove unneeded assignment in ccw_device_do_sense(). Signed-off-by: Cornelia Huck Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 062fb10..afc4e88 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -359,7 +359,7 @@ ccw_device_set_online(struct ccw_device *cdev) else pr_debug("ccw_device_offline returned %d, device %s\n", ret, cdev->dev.bus_id); - return (ret = 0) ? -ENODEV : ret; + return (ret == 0) ? -ENODEV : ret; } static ssize_t diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index dad4dd9..6c762b4 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c @@ -317,7 +317,6 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) /* * We have ending status but no sense information. Do a basic sense. */ - sch = to_subchannel(cdev->dev.parent); sch->sense_ccw.cmd_code = CCW_CMD_BASIC_SENSE; sch->sense_ccw.cda = (__u32) __pa(cdev->private->irb.ecw); sch->sense_ccw.count = SENSE_MAX_COUNT; -- cgit v0.10.2 From ed3d021b823336a2e0c5090a91d083243f756e6c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 17 Feb 2006 13:52:50 -0800 Subject: [PATCH] s390: sys32_fstatat -> sys32_fstatat64 Just rename the compat system call to keep the name consistent with all the other *64 compat system calls. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 2d02162..cc058dc 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -905,8 +905,8 @@ asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * sta return ret; } -asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename, - struct stat64_emu31 __user* statbuf, int flag) +asmlinkage long sys32_fstatat64(unsigned int dfd, char __user *filename, + struct stat64_emu31 __user* statbuf, int flag) { struct kstat stat; int error = -EINVAL; diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index dd2d6c3..615964c 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1523,13 +1523,13 @@ compat_sys_futimesat_wrapper: llgtr %r4,%r4 # struct timeval * jg compat_sys_futimesat - .globl sys32_fstatat_wrapper -sys32_fstatat_wrapper: + .globl sys32_fstatat64_wrapper +sys32_fstatat64_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # char * llgtr %r4,%r4 # struct stat64 * lgfr %r5,%r5 # int - jg sys32_fstatat + jg sys32_fstatat64 .globl sys_unlinkat_wrapper sys_unlinkat_wrapper: diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 84921fe..7c88d85 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -301,7 +301,7 @@ SYSCALL(sys_mkdirat,sys_mkdirat,sys_mkdirat_wrapper) SYSCALL(sys_mknodat,sys_mknodat,sys_mknodat_wrapper) /* 290 */ SYSCALL(sys_fchownat,sys_fchownat,sys_fchownat_wrapper) SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper) -SYSCALL(sys_fstatat64,sys_newfstatat,sys32_fstatat_wrapper) +SYSCALL(sys_fstatat64,sys_newfstatat,sys32_fstatat64_wrapper) SYSCALL(sys_unlinkat,sys_unlinkat,sys_unlinkat_wrapper) SYSCALL(sys_renameat,sys_renameat,sys_renameat_wrapper) /* 295 */ SYSCALL(sys_linkat,sys_linkat,sys_linkat_wrapper) -- cgit v0.10.2 From a8534adb74e23374889b84b3d97eb18da542a1b5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Feb 2006 13:52:51 -0800 Subject: [PATCH] swsusp: fix breakage with swap on LVM Restore the compatibility with the older code and make it possible to suspend if the kernel command line doesn't contain the "resume=" argument Signed-off-by: Rafael J. Wysocki Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 4e90905..2d9d08f 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -153,13 +153,11 @@ static int swsusp_swap_check(void) /* This is called before saving image */ { int i; - if (!swsusp_resume_device) - return -ENODEV; spin_lock(&swap_lock); for (i = 0; i < MAX_SWAPFILES; i++) { if (!(swap_info[i].flags & SWP_WRITEOK)) continue; - if (is_resume_device(swap_info + i)) { + if (!swsusp_resume_device || is_resume_device(swap_info + i)) { spin_unlock(&swap_lock); root_swap = i; return 0; -- cgit v0.10.2 From 77e7f250f88cd62844e24c42aff4d0e95969c746 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 17 Feb 2006 13:52:52 -0800 Subject: [PATCH] fuse: fix bug in aborted fuse_release_end() There's a rather theoretical case of the BUG triggering in fuse_reset_request(): - iget() fails because of OOM after a successful CREATE_OPEN request - during IO on the resulting RELEASE request the connection is aborted Fix and add warning to fuse_reset_request(). Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index f556a0d..0c9a2ee 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -66,6 +66,12 @@ static void restore_sigs(sigset_t *oldset) sigprocmask(SIG_SETMASK, oldset, NULL); } +/* + * Reset request, so that it can be reused + * + * The caller must be _very_ careful to make sure, that it is holding + * the only reference to req + */ void fuse_reset_request(struct fuse_req *req) { int preallocated = req->preallocated; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 2963516..6f05379 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -116,9 +116,14 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir) /* Special case for failed iget in CREATE */ static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) { - u64 nodeid = req->in.h.nodeid; - fuse_reset_request(req); - fuse_send_forget(fc, req, nodeid, 1); + /* If called from end_io_requests(), req has more than one + reference and fuse_reset_request() cannot work */ + if (fc->connected) { + u64 nodeid = req->in.h.nodeid; + fuse_reset_request(req); + fuse_send_forget(fc, req, nodeid, 1); + } else + fuse_put_request(fc, req); } void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff, -- cgit v0.10.2 From 9127dd1aace4e89acb48fbcafd0ed27d3869847b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 17 Feb 2006 13:52:54 -0800 Subject: [PATCH] allow windfarm_pm112 module to load The windfarm_pm112 module relies on smu_sat_get_sdb_partition which is in windfarm_smu_sat.c but is not exported to modules, so despite Kconfig having the option to build the pm112 as modules, this can never be loaded. This patch fixes that by exporting smu_sat_get_sdb_partition with EXPORT_SYMBOL_GPL Signed-off-by: Johannes Berg Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 3a32c59..24e51d5 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -151,6 +151,7 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, kfree(buf); return NULL; } +EXPORT_SYMBOL_GPL(smu_sat_get_sdb_partition); /* refresh the cache */ static int wf_sat_read_cache(struct wf_sat *sat) -- cgit v0.10.2 From 9ff4ced4676d3cd1f28b14d93a339f263ca304b0 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Fri, 17 Feb 2006 13:52:54 -0800 Subject: [PATCH] Remove KERN_INFO from middle of printk line Don't print KERN_INFO in the middle of a printk line. printk(KERN_INFO "OEM ID: %s ",str); is just above this. This is already fixed up in i386 copy. Signed-off-by: Martin J. Bligh Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index dc49bfb..9013a90 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c @@ -288,9 +288,9 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) memcpy(str,mpc->mpc_productid,12); str[12]=0; - printk(KERN_INFO "Product ID: %s ",str); + printk("Product ID: %s ",str); - printk(KERN_INFO "APIC at: 0x%X\n",mpc->mpc_lapic); + printk("APIC at: 0x%X\n",mpc->mpc_lapic); /* save the local APIC address, it might be non-default */ if (!acpi_lapic) -- cgit v0.10.2 From 200a4552af34b9a32e1f68a881a9ed5c7ec699cc Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 17 Feb 2006 13:52:56 -0800 Subject: [PATCH] powerpc: Fix accidentally-working typo in __pud_free_tlb One of the parameters to the __pud_free_tlb() macro for powerpc is incorrect (see patch) . We get away with it by accident, because the one place the macro is called, the second parameter is a variable named "pud". Signed-off-by: David Gibson Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h index 9f5b052..a00ee00 100644 --- a/include/asm-powerpc/pgalloc.h +++ b/include/asm-powerpc/pgalloc.h @@ -146,7 +146,7 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) #ifndef CONFIG_PPC_64K_PAGES -#define __pud_free_tlb(tlb, pmd) \ +#define __pud_free_tlb(tlb, pud) \ pgtable_free_tlb(tlb, pgtable_free_cache(pud, \ PUD_CACHE_NUM, PUD_TABLE_SIZE-1)) #endif /* CONFIG_PPC_64K_PAGES */ -- cgit v0.10.2 From 74910e6c7dc7471b286a883c1a7af70483ffd2ba Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 17 Feb 2006 13:52:58 -0800 Subject: [PATCH] select: time comparison fixes I got all of these backwards. We want to return min(input timeout, new timeout) to userspace to prevent increasing the time-remaining value. Thanks to Ernst Herzberg for reporting and diagnosing. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/compat.c b/fs/compat.c index a2ba78b..5333c7d 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1757,7 +1757,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, goto sticky; rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)); rtv.tv_sec = timeout; - if (compat_timeval_compare(&rtv, &tv) < 0) + if (compat_timeval_compare(&rtv, &tv) >= 0) rtv = tv; if (copy_to_user(tvp, &rtv, sizeof(rtv))) { sticky: @@ -1834,7 +1834,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, rts.tv_sec++; rts.tv_nsec -= NSEC_PER_SEC; } - if (compat_timespec_compare(&rts, &ts) < 0) + if (compat_timespec_compare(&rts, &ts) >= 0) rts = ts; copy_to_user(tsp, &rts, sizeof(rts)); } @@ -1934,7 +1934,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000; rts.tv_sec = timeout; - if (compat_timespec_compare(&rts, &ts) < 0) + if (compat_timespec_compare(&rts, &ts) >= 0) rts = ts; if (copy_to_user(tsp, &rts, sizeof(rts))) { sticky: diff --git a/fs/select.c b/fs/select.c index 6ce68a9..1815a57 100644 --- a/fs/select.c +++ b/fs/select.c @@ -404,7 +404,7 @@ asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, goto sticky; rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)); rtv.tv_sec = timeout; - if (timeval_compare(&rtv, &tv) < 0) + if (timeval_compare(&rtv, &tv) >= 0) rtv = tv; if (copy_to_user(tvp, &rtv, sizeof(rtv))) { sticky: @@ -471,7 +471,7 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp, rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000; rts.tv_sec = timeout; - if (timespec_compare(&rts, &ts) < 0) + if (timespec_compare(&rts, &ts) >= 0) rts = ts; if (copy_to_user(tsp, &rts, sizeof(rts))) { sticky: @@ -775,7 +775,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000; rts.tv_sec = timeout; - if (timespec_compare(&rts, &ts) < 0) + if (timespec_compare(&rts, &ts) >= 0) rts = ts; if (copy_to_user(tsp, &rts, sizeof(rts))) { sticky: -- cgit v0.10.2 From 636f13c174dd7c84a437d3c3e8fa66f03f7fda63 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Fri, 17 Feb 2006 13:59:36 -0800 Subject: [PATCH] sys_mbind sanity checking Make sure maxnodes is safe size before calculating nlongs in get_nodes(). Signed-off-by: Chris Wright Signed-off-by: Linus Torvalds diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 323fdcf..bedfa4f 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -808,6 +808,8 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask, nodes_clear(*nodes); if (maxnode == 0 || !nmask) return 0; + if (maxnode > PAGE_SIZE) + return -EINVAL; nlongs = BITS_TO_LONGS(maxnode); if ((maxnode % BITS_PER_LONG) == 0) -- cgit v0.10.2 From 35b73ceb9a7d10c81bd9e79e8485f7079ef2b40e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 17 Feb 2006 13:59:50 -0800 Subject: [PATCH] ACPI: fix vendor resource length computation acpi_rs_get_list_length() needs to account for all the vendor-defined data bytes. Failing to include these causes buffers to be sized too small, which causes slab corruption when we later convert AML to resources and run off the end of the buffer. This causes slab corruption on machines that use ACPI vendor-defined resources. All HP ia64 machines do, and I'm told that some NEC machines may as well. Signed-off-by: Bjorn Helgaas Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 7d6481d..4038dbf 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -391,8 +391,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, * Ensure a 32-bit boundary for the structure */ extra_struct_bytes = - ACPI_ROUND_UP_to_32_bITS(resource_length) - - resource_length; + ACPI_ROUND_UP_to_32_bITS(resource_length); break; case ACPI_RESOURCE_NAME_END_TAG: @@ -408,8 +407,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, * Add vendor data and ensure a 32-bit boundary for the structure */ extra_struct_bytes = - ACPI_ROUND_UP_to_32_bITS(resource_length) - - resource_length; + ACPI_ROUND_UP_to_32_bITS(resource_length); break; case ACPI_RESOURCE_NAME_ADDRESS32: -- cgit v0.10.2 From bd71c2b17468a2531fb4c81ec1d73520845e97e1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 17 Feb 2006 14:23:45 -0800 Subject: Linux v2.6.16-rc4 diff --git a/Makefile b/Makefile index 48d569d..77a448c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 16 -EXTRAVERSION =-rc3 +EXTRAVERSION =-rc4 NAME=Sliding Snow Leopard # *DOCUMENTATION* -- cgit v0.10.2