mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge ../scsi-rc-fixes-2.6
This commit is contained in:
commit
0bd2af4683
1886 changed files with 57083 additions and 18670 deletions
|
|
@ -14,6 +14,10 @@ source "drivers/pnp/Kconfig"
|
|||
|
||||
source "drivers/block/Kconfig"
|
||||
|
||||
# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
|
||||
|
||||
source "drivers/misc/Kconfig"
|
||||
|
||||
source "drivers/ide/Kconfig"
|
||||
|
||||
source "drivers/scsi/Kconfig"
|
||||
|
|
@ -52,8 +56,6 @@ source "drivers/w1/Kconfig"
|
|||
|
||||
source "drivers/hwmon/Kconfig"
|
||||
|
||||
source "drivers/misc/Kconfig"
|
||||
|
||||
source "drivers/mfd/Kconfig"
|
||||
|
||||
source "drivers/media/Kconfig"
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ struct acpi_memory_device {
|
|||
struct list_head res_list;
|
||||
};
|
||||
|
||||
static int acpi_hotmem_initialized;
|
||||
|
||||
static acpi_status
|
||||
acpi_memory_get_resource(struct acpi_resource *resource, void *context)
|
||||
{
|
||||
|
|
@ -414,7 +416,7 @@ static int acpi_memory_device_add(struct acpi_device *device)
|
|||
/* Set the device state */
|
||||
mem_device->state = MEMORY_POWER_ON_STATE;
|
||||
|
||||
printk(KERN_INFO "%s \n", acpi_device_name(device));
|
||||
printk(KERN_DEBUG "%s \n", acpi_device_name(device));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -438,6 +440,15 @@ static int acpi_memory_device_start (struct acpi_device *device)
|
|||
struct acpi_memory_device *mem_device;
|
||||
int result = 0;
|
||||
|
||||
/*
|
||||
* Early boot code has recognized memory area by EFI/E820.
|
||||
* If DSDT shows these memory devices on boot, hotplug is not necessary
|
||||
* for them. So, it just returns until completion of this driver's
|
||||
* start up.
|
||||
*/
|
||||
if (!acpi_hotmem_initialized)
|
||||
return 0;
|
||||
|
||||
mem_device = acpi_driver_data(device);
|
||||
|
||||
if (!acpi_memory_check_device(mem_device)) {
|
||||
|
|
@ -537,6 +548,7 @@ static int __init acpi_memory_device_init(void)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
acpi_hotmem_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ struct asus_hotk {
|
|||
S2x, //S200 (J1 reported), Victor MP-XP7210
|
||||
W1N, //W1000N
|
||||
W5A, //W5A
|
||||
W3V, //W3030V
|
||||
xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
|
||||
//(Centrino)
|
||||
END_MODEL
|
||||
|
|
@ -376,6 +377,17 @@ static struct model_data model_conf[END_MODEL] = {
|
|||
.display_get = "\\ADVG"},
|
||||
|
||||
{
|
||||
.name = "W3V",
|
||||
.mt_mled = "MLED",
|
||||
.mt_wled = "WLED",
|
||||
.mt_lcd_switch = xxN_PREFIX "_Q10",
|
||||
.lcd_status = "\\BKLT",
|
||||
.brightness_set = "SPLV",
|
||||
.brightness_get = "GPLV",
|
||||
.display_set = "SDSP",
|
||||
.display_get = "\\INFB"},
|
||||
|
||||
{
|
||||
.name = "xxN",
|
||||
.mt_mled = "MLED",
|
||||
/* WLED present, but not controlled by ACPI */
|
||||
|
|
@ -555,11 +567,11 @@ static int
|
|||
write_led(const char __user * buffer, unsigned long count,
|
||||
char *ledname, int ledmask, int invert)
|
||||
{
|
||||
int value;
|
||||
int rv, value;
|
||||
int led_out = 0;
|
||||
|
||||
count = parse_arg(buffer, count, &value);
|
||||
if (count > 0)
|
||||
rv = parse_arg(buffer, count, &value);
|
||||
if (rv > 0)
|
||||
led_out = value ? 1 : 0;
|
||||
|
||||
hotk->status =
|
||||
|
|
@ -572,7 +584,7 @@ write_led(const char __user * buffer, unsigned long count,
|
|||
printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
|
||||
ledname);
|
||||
|
||||
return count;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -607,20 +619,18 @@ static int
|
|||
proc_write_ledd(struct file *file, const char __user * buffer,
|
||||
unsigned long count, void *data)
|
||||
{
|
||||
int value;
|
||||
int rv, value;
|
||||
|
||||
count = parse_arg(buffer, count, &value);
|
||||
if (count > 0) {
|
||||
rv = parse_arg(buffer, count, &value);
|
||||
if (rv > 0) {
|
||||
if (!write_acpi_int
|
||||
(hotk->handle, hotk->methods->mt_ledd, value, NULL))
|
||||
printk(KERN_WARNING
|
||||
"Asus ACPI: LED display write failed\n");
|
||||
else
|
||||
hotk->ledd_status = (u32) value;
|
||||
} else if (count < 0)
|
||||
printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
|
||||
|
||||
return count;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -761,12 +771,12 @@ static int
|
|||
proc_write_lcd(struct file *file, const char __user * buffer,
|
||||
unsigned long count, void *data)
|
||||
{
|
||||
int value;
|
||||
int rv, value;
|
||||
|
||||
count = parse_arg(buffer, count, &value);
|
||||
if (count > 0)
|
||||
rv = parse_arg(buffer, count, &value);
|
||||
if (rv > 0)
|
||||
set_lcd_state(value);
|
||||
return count;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int read_brightness(void)
|
||||
|
|
@ -830,18 +840,15 @@ static int
|
|||
proc_write_brn(struct file *file, const char __user * buffer,
|
||||
unsigned long count, void *data)
|
||||
{
|
||||
int value;
|
||||
int rv, value;
|
||||
|
||||
count = parse_arg(buffer, count, &value);
|
||||
if (count > 0) {
|
||||
rv = parse_arg(buffer, count, &value);
|
||||
if (rv > 0) {
|
||||
value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
|
||||
/* 0 <= value <= 15 */
|
||||
set_brightness(value);
|
||||
} else if (count < 0) {
|
||||
printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
|
||||
}
|
||||
|
||||
return count;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void set_display(int value)
|
||||
|
|
@ -880,15 +887,12 @@ static int
|
|||
proc_write_disp(struct file *file, const char __user * buffer,
|
||||
unsigned long count, void *data)
|
||||
{
|
||||
int value;
|
||||
int rv, value;
|
||||
|
||||
count = parse_arg(buffer, count, &value);
|
||||
if (count > 0)
|
||||
rv = parse_arg(buffer, count, &value);
|
||||
if (rv > 0)
|
||||
set_display(value);
|
||||
else if (count < 0)
|
||||
printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
|
||||
|
||||
return count;
|
||||
return rv;
|
||||
}
|
||||
|
||||
typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
|
||||
|
|
@ -1097,6 +1101,8 @@ static int asus_model_match(char *model)
|
|||
return A4G;
|
||||
else if (strncmp(model, "W1N", 3) == 0)
|
||||
return W1N;
|
||||
else if (strncmp(model, "W3V", 3) == 0)
|
||||
return W3V;
|
||||
else if (strncmp(model, "W5A", 3) == 0)
|
||||
return W5A;
|
||||
else
|
||||
|
|
@ -1200,9 +1206,10 @@ static int asus_hotk_get_info(void)
|
|||
hotk->methods->mt_wled = NULL;
|
||||
/* L5D's WLED is not controlled by ACPI */
|
||||
else if (strncmp(string, "M2N", 3) == 0 ||
|
||||
strncmp(string, "W3V", 3) == 0 ||
|
||||
strncmp(string, "S1N", 3) == 0)
|
||||
hotk->methods->mt_wled = "WLED";
|
||||
/* M2N and S1N have a usable WLED */
|
||||
/* M2N, S1N and W3V have a usable WLED */
|
||||
else if (asus_info) {
|
||||
if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
|
||||
hotk->methods->mled_status = NULL;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
|
|||
|
||||
static int acpi_battery_add(struct acpi_device *device);
|
||||
static int acpi_battery_remove(struct acpi_device *device, int type);
|
||||
static int acpi_battery_resume(struct acpi_device *device, int status);
|
||||
|
||||
static struct acpi_driver acpi_battery_driver = {
|
||||
.name = ACPI_BATTERY_DRIVER_NAME,
|
||||
|
|
@ -71,6 +72,7 @@ static struct acpi_driver acpi_battery_driver = {
|
|||
.ids = ACPI_BATTERY_HID,
|
||||
.ops = {
|
||||
.add = acpi_battery_add,
|
||||
.resume = acpi_battery_resume,
|
||||
.remove = acpi_battery_remove,
|
||||
},
|
||||
};
|
||||
|
|
@ -753,6 +755,18 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* this is needed to learn about changes made in suspended state */
|
||||
static int acpi_battery_resume(struct acpi_device *device, int state)
|
||||
{
|
||||
struct acpi_battery *battery;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
battery = device->driver_data;
|
||||
return acpi_battery_check(battery);
|
||||
}
|
||||
|
||||
static int __init acpi_battery_init(void)
|
||||
{
|
||||
int result;
|
||||
|
|
|
|||
1108
drivers/acpi/ec.c
1108
drivers/acpi/ec.c
File diff suppressed because it is too large
Load diff
|
|
@ -342,20 +342,8 @@ static u32 acpi_ev_global_lock_handler(void *context)
|
|||
if (acquired) {
|
||||
|
||||
/* Got the lock, now wake all threads waiting for it */
|
||||
|
||||
acpi_gbl_global_lock_acquired = TRUE;
|
||||
|
||||
/* Run the Global Lock thread which will signal all waiting threads */
|
||||
|
||||
status =
|
||||
acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
|
||||
acpi_ev_global_lock_thread, context);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Could not queue Global Lock thread"));
|
||||
|
||||
return (ACPI_INTERRUPT_NOT_HANDLED);
|
||||
}
|
||||
acpi_ev_global_lock_thread(context);
|
||||
}
|
||||
|
||||
return (ACPI_INTERRUPT_HANDLED);
|
||||
|
|
|
|||
|
|
@ -225,13 +225,12 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
|
|||
if (!
|
||||
(ACPI_STRNCMP
|
||||
(object_hID.value, PCI_ROOT_HID_STRING,
|
||||
sizeof(PCI_ROOT_HID_STRING))
|
||||
||
|
||||
!(ACPI_STRNCMP
|
||||
(object_hID.value,
|
||||
PCI_EXPRESS_ROOT_HID_STRING,
|
||||
sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
|
||||
{
|
||||
sizeof(PCI_ROOT_HID_STRING)))
|
||||
||
|
||||
!(ACPI_STRNCMP
|
||||
(object_hID.value,
|
||||
PCI_EXPRESS_ROOT_HID_STRING,
|
||||
sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
|
||||
|
||||
/* Install a handler for this PCI root bridge */
|
||||
|
||||
|
|
|
|||
|
|
@ -1702,13 +1702,11 @@ static struct ibm_struct ibms[] = {
|
|||
.name = "brightness",
|
||||
.read = brightness_read,
|
||||
.write = brightness_write,
|
||||
.experimental = 1,
|
||||
},
|
||||
{
|
||||
.name = "volume",
|
||||
.read = volume_read,
|
||||
.write = volume_write,
|
||||
.experimental = 1,
|
||||
},
|
||||
{
|
||||
.name = "fan",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,12 @@ ACPI_MODULE_NAME("acpi_motherboard")
|
|||
* the io ports if they really know they can use it, while
|
||||
* still preventing hotplug PCI devices from using it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01
|
||||
* and PNP0C02, redundant with acpi_reserve_io_ranges().
|
||||
* But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP.
|
||||
*/
|
||||
static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data)
|
||||
{
|
||||
struct resource *requested_res = NULL;
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
|
|||
if (!link || !irq)
|
||||
return -EINVAL;
|
||||
|
||||
resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC);
|
||||
resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
|
||||
if (!resource)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -216,10 +216,8 @@ static int acpi_power_off_device(acpi_handle handle)
|
|||
{
|
||||
int result = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_device *device = NULL;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
|
||||
|
||||
result = acpi_power_get_context(handle, &resource);
|
||||
if (result)
|
||||
return result;
|
||||
|
|
@ -230,13 +228,13 @@ static int acpi_power_off_device(acpi_handle handle)
|
|||
if (resource->references) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Resource [%s] is still in use, dereferencing\n",
|
||||
device->pnp.bus_id));
|
||||
resource->device->pnp.bus_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
|
||||
device->pnp.bus_id));
|
||||
resource->device->pnp.bus_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -251,8 +249,7 @@ static int acpi_power_off_device(acpi_handle handle)
|
|||
return -ENOEXEC;
|
||||
|
||||
/* Update the power resource's _device_ power state */
|
||||
device = resource->device;
|
||||
device->power.state = ACPI_STATE_D3;
|
||||
resource->device->power.state = ACPI_STATE_D3;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
|
||||
resource->name));
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
|
|||
|
||||
static void *processor_device_array[NR_CPUS];
|
||||
|
||||
static int acpi_processor_start(struct acpi_device *device)
|
||||
static int __cpuinit acpi_processor_start(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
acpi_status status = AE_OK;
|
||||
|
|
|
|||
|
|
@ -219,6 +219,23 @@ static void acpi_safe_halt(void)
|
|||
|
||||
static atomic_t c3_cpu_count;
|
||||
|
||||
/* Common C-state entry for C2, C3, .. */
|
||||
static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
|
||||
{
|
||||
if (cstate->space_id == ACPI_CSTATE_FFH) {
|
||||
/* Call into architectural FFH based C-state */
|
||||
acpi_processor_ffh_cstate_enter(cstate);
|
||||
} else {
|
||||
int unused;
|
||||
/* IO port based C-state */
|
||||
inb(cstate->address);
|
||||
/* Dummy wait op - must do something useless after P_LVL2 read
|
||||
because chipsets cannot guarantee that STPCLK# signal
|
||||
gets asserted in time to freeze execution properly. */
|
||||
unused = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_processor_idle(void)
|
||||
{
|
||||
struct acpi_processor *pr = NULL;
|
||||
|
|
@ -361,11 +378,7 @@ static void acpi_processor_idle(void)
|
|||
/* Get start time (ticks) */
|
||||
t1 = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
/* Invoke C2 */
|
||||
inb(cx->address);
|
||||
/* Dummy wait op - must do something useless after P_LVL2 read
|
||||
because chipsets cannot guarantee that STPCLK# signal
|
||||
gets asserted in time to freeze execution properly. */
|
||||
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
acpi_cstate_enter(cx);
|
||||
/* Get end time (ticks) */
|
||||
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
|
||||
|
|
@ -401,9 +414,7 @@ static void acpi_processor_idle(void)
|
|||
/* Get start time (ticks) */
|
||||
t1 = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
/* Invoke C3 */
|
||||
inb(cx->address);
|
||||
/* Dummy wait op (see above) */
|
||||
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
acpi_cstate_enter(cx);
|
||||
/* Get end time (ticks) */
|
||||
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
|
||||
if (pr->flags.bm_check) {
|
||||
|
|
@ -628,20 +639,16 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr)
|
||||
static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
|
||||
{
|
||||
|
||||
/* Zero initialize all the C-states info. */
|
||||
memset(pr->power.states, 0, sizeof(pr->power.states));
|
||||
|
||||
/* set the first C-State to C1 */
|
||||
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
|
||||
|
||||
/* the C0 state only exists as a filler in our array,
|
||||
* and all processors need to support C1 */
|
||||
if (!pr->power.states[ACPI_STATE_C1].valid) {
|
||||
/* set the first C-State to C1 */
|
||||
/* all processors need to support C1 */
|
||||
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
|
||||
pr->power.states[ACPI_STATE_C1].valid = 1;
|
||||
}
|
||||
/* the C0 state only exists as a filler in our array */
|
||||
pr->power.states[ACPI_STATE_C0].valid = 1;
|
||||
pr->power.states[ACPI_STATE_C1].valid = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -658,12 +665,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
|
|||
if (nocst)
|
||||
return -ENODEV;
|
||||
|
||||
current_count = 1;
|
||||
|
||||
/* Zero initialize C2 onwards and prepare for fresh CST lookup */
|
||||
for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++)
|
||||
memset(&(pr->power.states[i]), 0,
|
||||
sizeof(struct acpi_processor_cx));
|
||||
current_count = 0;
|
||||
|
||||
status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
|
|
@ -718,22 +720,39 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
|
|||
(reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
|
||||
continue;
|
||||
|
||||
cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
|
||||
0 : reg->address;
|
||||
|
||||
/* There should be an easy way to extract an integer... */
|
||||
obj = (union acpi_object *)&(element->package.elements[1]);
|
||||
if (obj->type != ACPI_TYPE_INTEGER)
|
||||
continue;
|
||||
|
||||
cx.type = obj->integer.value;
|
||||
/*
|
||||
* Some buggy BIOSes won't list C1 in _CST -
|
||||
* Let acpi_processor_get_power_info_default() handle them later
|
||||
*/
|
||||
if (i == 1 && cx.type != ACPI_STATE_C1)
|
||||
current_count++;
|
||||
|
||||
if ((cx.type != ACPI_STATE_C1) &&
|
||||
(reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
|
||||
continue;
|
||||
cx.address = reg->address;
|
||||
cx.index = current_count + 1;
|
||||
|
||||
if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
|
||||
continue;
|
||||
cx.space_id = ACPI_CSTATE_SYSTEMIO;
|
||||
if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
|
||||
if (acpi_processor_ffh_cstate_probe
|
||||
(pr->id, &cx, reg) == 0) {
|
||||
cx.space_id = ACPI_CSTATE_FFH;
|
||||
} else if (cx.type != ACPI_STATE_C1) {
|
||||
/*
|
||||
* C1 is a special case where FIXED_HARDWARE
|
||||
* can be handled in non-MWAIT way as well.
|
||||
* In that case, save this _CST entry info.
|
||||
* That is, we retain space_id of SYSTEM_IO for
|
||||
* halt based C1.
|
||||
* Otherwise, ignore this info and continue.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
obj = (union acpi_object *)&(element->package.elements[2]);
|
||||
if (obj->type != ACPI_TYPE_INTEGER)
|
||||
|
|
@ -938,11 +957,17 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
|
|||
/* NOTE: the idle thread may not be running while calling
|
||||
* this function */
|
||||
|
||||
/* Adding C1 state */
|
||||
acpi_processor_get_power_info_default_c1(pr);
|
||||
/* Zero initialize all the C-states info. */
|
||||
memset(pr->power.states, 0, sizeof(pr->power.states));
|
||||
|
||||
result = acpi_processor_get_power_info_cst(pr);
|
||||
if (result == -ENODEV)
|
||||
acpi_processor_get_power_info_fadt(pr);
|
||||
result = acpi_processor_get_power_info_fadt(pr);
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
acpi_processor_get_power_info_default(pr);
|
||||
|
||||
pr->power.count = acpi_processor_power_verify(pr);
|
||||
|
||||
|
|
@ -1083,6 +1108,7 @@ static const struct file_operations acpi_processor_power_fops = {
|
|||
.release = single_release,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static void smp_callback(void *v)
|
||||
{
|
||||
/* we already woke the CPU up, nothing more to do */
|
||||
|
|
@ -1104,8 +1130,9 @@ static int acpi_processor_latency_notify(struct notifier_block *b,
|
|||
static struct notifier_block acpi_processor_latency_notifier = {
|
||||
.notifier_call = acpi_processor_latency_notify,
|
||||
};
|
||||
#endif
|
||||
|
||||
int acpi_processor_power_init(struct acpi_processor *pr,
|
||||
int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
|
||||
struct acpi_device *device)
|
||||
{
|
||||
acpi_status status = 0;
|
||||
|
|
@ -1121,7 +1148,9 @@ int acpi_processor_power_init(struct acpi_processor *pr,
|
|||
"ACPI: processor limited to max C-state %d\n",
|
||||
max_cstate);
|
||||
first_run++;
|
||||
#ifdef CONFIG_SMP
|
||||
register_latency_notifier(&acpi_processor_latency_notifier);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!pr)
|
||||
|
|
@ -1193,7 +1222,9 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
|
|||
* copies of pm_idle before proceeding.
|
||||
*/
|
||||
cpu_idle_wait();
|
||||
#ifdef CONFIG_SMP
|
||||
unregister_latency_notifier(&acpi_processor_latency_notifier);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -98,11 +98,11 @@ static int update_info_mode = UPDATE_INFO_MODE;
|
|||
static int update_time = UPDATE_TIME;
|
||||
static int update_time2 = UPDATE_TIME2;
|
||||
|
||||
module_param(capacity_mode, int, CAPACITY_UNIT);
|
||||
module_param(update_mode, int, UPDATE_MODE);
|
||||
module_param(update_info_mode, int, UPDATE_INFO_MODE);
|
||||
module_param(update_time, int, UPDATE_TIME);
|
||||
module_param(update_time2, int, UPDATE_TIME2);
|
||||
module_param(capacity_mode, int, 0);
|
||||
module_param(update_mode, int, 0);
|
||||
module_param(update_info_mode, int, 0);
|
||||
module_param(update_time, int, 0);
|
||||
module_param(update_time2, int, 0);
|
||||
|
||||
static int acpi_sbs_add(struct acpi_device *device);
|
||||
static int acpi_sbs_remove(struct acpi_device *device, int type);
|
||||
|
|
@ -1685,10 +1685,16 @@ static int acpi_sbs_add(struct acpi_device *device)
|
|||
|
||||
int acpi_sbs_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device);
|
||||
struct acpi_sbs *sbs = NULL;
|
||||
int id;
|
||||
|
||||
if (!device || !sbs) {
|
||||
if (!device) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sbs = (struct acpi_sbs *)acpi_driver_data(device);
|
||||
|
||||
if (!sbs) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
|
|||
|
||||
if (header->length < sizeof(struct acpi_table_header)) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Table length (%X) is smaller than minimum (%X)",
|
||||
"Table length (%X) is smaller than minimum (%zX)",
|
||||
header->length, sizeof(struct acpi_table_header)));
|
||||
|
||||
return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
|
|||
|
||||
if (table_ptr->length < sizeof(struct acpi_table_header)) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"RSDT/XSDT length (%X) is smaller than minimum (%X)",
|
||||
"RSDT/XSDT length (%X) is smaller than minimum (%zX)",
|
||||
table_ptr->length,
|
||||
sizeof(struct acpi_table_header)));
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ menu "Serial ATA (prod) and Parallel ATA (experimental) drivers"
|
|||
|
||||
config ATA
|
||||
tristate "ATA device support"
|
||||
depends on BLOCK
|
||||
depends on !(M32R || M68K) || BROKEN
|
||||
depends on !SUN4 || BROKEN
|
||||
select SCSI
|
||||
|
|
|
|||
|
|
@ -334,6 +334,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0557), board_ahci }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0558), board_ahci }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */
|
||||
|
||||
/* SiS */
|
||||
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
|
||||
|
|
@ -736,8 +744,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
|||
}
|
||||
|
||||
/* check BUSY/DRQ, perform Command List Override if necessary */
|
||||
ahci_tf_read(ap, &tf);
|
||||
if (tf.command & (ATA_BUSY | ATA_DRQ)) {
|
||||
if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) {
|
||||
rc = ahci_clo(ap);
|
||||
|
||||
if (rc == -EOPNOTSUPP) {
|
||||
|
|
@ -1041,7 +1048,7 @@ static void ahci_host_intr(struct ata_port *ap)
|
|||
/* hmmm... a spurious interupt */
|
||||
|
||||
/* some devices send D2H reg with I bit set during NCQ command phase */
|
||||
if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS)
|
||||
if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
|
||||
return;
|
||||
|
||||
/* ignore interim PIO setup fis interrupts */
|
||||
|
|
|
|||
|
|
@ -126,8 +126,7 @@ enum {
|
|||
ich6_sata = 7,
|
||||
ich6_sata_ahci = 8,
|
||||
ich6m_sata_ahci = 9,
|
||||
ich7m_sata_ahci = 10,
|
||||
ich8_sata_ahci = 11,
|
||||
ich8_sata_ahci = 10,
|
||||
|
||||
/* constants for mapping table */
|
||||
P0 = 0, /* port 0 */
|
||||
|
|
@ -227,7 +226,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
|
|||
/* 82801GB/GR/GH (ICH7, identical to ICH6) */
|
||||
{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
|
||||
/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
|
||||
{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7m_sata_ahci },
|
||||
{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
|
||||
/* Enterprise Southbridge 2 (where's the datasheet?) */
|
||||
{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
|
||||
/* SATA Controller 1 IDE (ICH8, no datasheet yet) */
|
||||
|
|
@ -399,23 +398,10 @@ static const struct piix_map_db ich6m_map_db = {
|
|||
.mask = 0x3,
|
||||
.port_enable = 0x5,
|
||||
.present_shift = 4,
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
{ P0, P2, RV, RV }, /* 00b */
|
||||
{ RV, RV, RV, RV },
|
||||
{ P0, P2, IDE, IDE }, /* 10b */
|
||||
{ RV, RV, RV, RV },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct piix_map_db ich7m_map_db = {
|
||||
.mask = 0x3,
|
||||
.port_enable = 0x5,
|
||||
.present_shift = 4,
|
||||
|
||||
/* Map 01b isn't specified in the doc but some notebooks use
|
||||
* it anyway. ATM, the only case spotted carries subsystem ID
|
||||
* 1025:0107. This is the only difference from ich6m.
|
||||
* it anyway. MAP 01b have been spotted on both ICH6M and
|
||||
* ICH7M.
|
||||
*/
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
|
|
@ -432,9 +418,9 @@ static const struct piix_map_db ich8_map_db = {
|
|||
.present_shift = 8,
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
{ P0, NA, P1, NA }, /* 00b (hardwired) */
|
||||
{ P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */
|
||||
{ RV, RV, RV, RV },
|
||||
{ RV, RV, RV, RV }, /* 10b (never) */
|
||||
{ IDE, IDE, NA, NA }, /* 10b (IDE mode) */
|
||||
{ RV, RV, RV, RV },
|
||||
},
|
||||
};
|
||||
|
|
@ -445,7 +431,6 @@ static const struct piix_map_db *piix_map_db_table[] = {
|
|||
[ich6_sata] = &ich6_map_db,
|
||||
[ich6_sata_ahci] = &ich6_map_db,
|
||||
[ich6m_sata_ahci] = &ich6m_map_db,
|
||||
[ich7m_sata_ahci] = &ich7m_map_db,
|
||||
[ich8_sata_ahci] = &ich8_map_db,
|
||||
};
|
||||
|
||||
|
|
@ -556,19 +541,7 @@ static struct ata_port_info piix_port_info[] = {
|
|||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich7m_sata_ahci: 10 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA |
|
||||
PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
|
||||
PIIX_FLAG_AHCI,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich8_sata_ahci: 11 */
|
||||
/* ich8_sata_ahci: 10 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA |
|
||||
|
|
|
|||
|
|
@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
|
|||
* the PIO timing number for the maximum. Turn it into
|
||||
* a mask.
|
||||
*/
|
||||
pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
|
||||
u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF;
|
||||
if (mode < 5) /* Valid PIO range */
|
||||
pio_mask = (2 << mode) - 1;
|
||||
else
|
||||
pio_mask = 1;
|
||||
|
||||
/* But wait.. there's more. Design your standards by
|
||||
* committee and you too can get a free iordy field to
|
||||
|
|
@ -5953,7 +5957,7 @@ static void __exit ata_exit(void)
|
|||
destroy_workqueue(ata_aux_wq);
|
||||
}
|
||||
|
||||
module_init(ata_init);
|
||||
subsys_initcall(ata_init);
|
||||
module_exit(ata_exit);
|
||||
|
||||
static unsigned long ratelimit_time;
|
||||
|
|
@ -6118,7 +6122,6 @@ EXPORT_SYMBOL_GPL(ata_std_prereset);
|
|||
EXPORT_SYMBOL_GPL(ata_std_softreset);
|
||||
EXPORT_SYMBOL_GPL(sata_std_hardreset);
|
||||
EXPORT_SYMBOL_GPL(ata_std_postreset);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_revalidate);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_classify);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_pair);
|
||||
EXPORT_SYMBOL_GPL(ata_port_disable);
|
||||
|
|
|
|||
|
|
@ -164,10 +164,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||
{
|
||||
int rc = 0;
|
||||
u8 scsi_cmd[MAX_COMMAND_SIZE];
|
||||
u8 args[4], *argbuf = NULL;
|
||||
u8 args[4], *argbuf = NULL, *sensebuf = NULL;
|
||||
int argsize = 0;
|
||||
struct scsi_sense_hdr sshdr;
|
||||
enum dma_data_direction data_dir;
|
||||
int cmd_result;
|
||||
|
||||
if (arg == NULL)
|
||||
return -EINVAL;
|
||||
|
|
@ -175,6 +175,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||
if (copy_from_user(args, arg, sizeof(args)))
|
||||
return -EFAULT;
|
||||
|
||||
sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
|
||||
if (!sensebuf)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(scsi_cmd, 0, sizeof(scsi_cmd));
|
||||
|
||||
if (args[3]) {
|
||||
|
|
@ -191,7 +195,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||
data_dir = DMA_FROM_DEVICE;
|
||||
} else {
|
||||
scsi_cmd[1] = (3 << 1); /* Non-data */
|
||||
/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
|
||||
scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */
|
||||
data_dir = DMA_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -210,18 +214,46 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||
|
||||
/* Good values for timeout and retries? Values below
|
||||
from scsi_ioctl_send_command() for default case... */
|
||||
if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize,
|
||||
&sshdr, (10*HZ), 5)) {
|
||||
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
|
||||
sensebuf, (10*HZ), 5, 0);
|
||||
|
||||
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
|
||||
u8 *desc = sensebuf + 8;
|
||||
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
|
||||
|
||||
/* If we set cc then ATA pass-through will cause a
|
||||
* check condition even if no error. Filter that. */
|
||||
if (cmd_result & SAM_STAT_CHECK_CONDITION) {
|
||||
struct scsi_sense_hdr sshdr;
|
||||
scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
|
||||
&sshdr);
|
||||
if (sshdr.sense_key==0 &&
|
||||
sshdr.asc==0 && sshdr.ascq==0)
|
||||
cmd_result &= ~SAM_STAT_CHECK_CONDITION;
|
||||
}
|
||||
|
||||
/* Send userspace a few ATA registers (same as drivers/ide) */
|
||||
if (sensebuf[0] == 0x72 && /* format is "descriptor" */
|
||||
desc[0] == 0x09 ) { /* code is "ATA Descriptor" */
|
||||
args[0] = desc[13]; /* status */
|
||||
args[1] = desc[3]; /* error */
|
||||
args[2] = desc[5]; /* sector count (0:7) */
|
||||
if (copy_to_user(arg, args, sizeof(args)))
|
||||
rc = -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cmd_result) {
|
||||
rc = -EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Need code to retrieve data from check condition? */
|
||||
|
||||
if ((argbuf)
|
||||
&& copy_to_user(arg + sizeof(args), argbuf, argsize))
|
||||
rc = -EFAULT;
|
||||
error:
|
||||
kfree(sensebuf);
|
||||
kfree(argbuf);
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1580,9 +1612,9 @@ early_finish:
|
|||
|
||||
err_did:
|
||||
ata_qc_free(qc);
|
||||
err_mem:
|
||||
cmd->result = (DID_ERROR << 16);
|
||||
done(cmd);
|
||||
err_mem:
|
||||
DPRINTK("EXIT - internal\n");
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -981,6 +981,15 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
|
|||
mask = (1 << 2) | (1 << 0);
|
||||
if ((tmp8 & mask) != mask)
|
||||
legacy_mode = (1 << 3);
|
||||
#if defined(CONFIG_NO_ATA_LEGACY)
|
||||
/* Some platforms with PCI limits cannot address compat
|
||||
port space. In that case we punt if their firmware has
|
||||
left a device in compatibility mode */
|
||||
if (legacy_mode) {
|
||||
printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = pci_request_regions(pdev, DRV_NAME);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ extern unsigned ata_exec_internal(struct ata_device *dev,
|
|||
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
|
||||
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
int post_reset, u16 *id);
|
||||
extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
|
||||
extern int ata_dev_configure(struct ata_device *dev, int print_info);
|
||||
extern int sata_down_spd_limit(struct ata_port *ap);
|
||||
extern int sata_set_spd_needed(struct ata_port *ap);
|
||||
|
|
|
|||
|
|
@ -677,6 +677,8 @@ static const struct pci_device_id amd[] = {
|
|||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 8 },
|
||||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 8 },
|
||||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 8 },
|
||||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE), 8 },
|
||||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE), 8 },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 },
|
||||
|
||||
{ },
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ static int artop6260_pre_reset(struct ata_port *ap)
|
|||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x49, &tmp);
|
||||
if (tmp & (1 >> ap->port_no))
|
||||
if (tmp & (1 << ap->port_no))
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt37x"
|
||||
#define DRV_VERSION "0.5"
|
||||
#define DRV_VERSION "0.5.1"
|
||||
|
||||
struct hpt_clock {
|
||||
u8 xfer_speed;
|
||||
|
|
@ -453,7 +453,13 @@ static int hpt37x_pre_reset(struct ata_port *ap)
|
|||
{
|
||||
u8 scr2, ata66;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
static const struct pci_bits hpt37x_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
{ 0x54, 1, 0x04, 0x04 }
|
||||
};
|
||||
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x5B, &scr2);
|
||||
pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
|
||||
/* Cable register now active */
|
||||
|
|
@ -488,10 +494,17 @@ static void hpt37x_error_handler(struct ata_port *ap)
|
|||
|
||||
static int hpt374_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
static const struct pci_bits hpt37x_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
{ 0x54, 1, 0x04, 0x04 }
|
||||
};
|
||||
u16 mcr3, mcr6;
|
||||
u8 ata66;
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
/* Do the extra channel work */
|
||||
pci_read_config_word(pdev, 0x52, &mcr3);
|
||||
pci_read_config_word(pdev, 0x56, &mcr6);
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned
|
|||
memcpy(&pad, buf + buflen - slop, slop);
|
||||
outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
||||
} else {
|
||||
pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
|
||||
pad = cpu_to_le32(inl(ap->ioaddr.data_addr));
|
||||
memcpy(buf + buflen - slop, &pad, slop);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,10 +117,14 @@ static const struct pci_device_id nv_pci_tbl[] = {
|
|||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
|
||||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
|
||||
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045c), GENERIC },
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045d), GENERIC },
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045e), GENERIC },
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045f), GENERIC },
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
|
||||
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
|
||||
PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
|
|||
#if 0
|
||||
{ PCI_VDEVICE(PROMISE, 0x3570), board_20771 },
|
||||
#endif
|
||||
{ PCI_VDEVICE(PROMISE, 0x3577), board_20771 },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
struct ata_probe_ent *probe_ent = NULL;
|
||||
int rc;
|
||||
u32 genctl;
|
||||
struct ata_port_info *ppi[2];
|
||||
struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
|
||||
int pci_dev_busy = 0;
|
||||
u8 pmr;
|
||||
u8 port2_start;
|
||||
|
|
@ -265,27 +265,20 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
goto err_out_regions;
|
||||
|
||||
ppi[0] = ppi[1] = &sis_port_info;
|
||||
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
|
||||
if (!probe_ent) {
|
||||
rc = -ENOMEM;
|
||||
goto err_out_regions;
|
||||
}
|
||||
|
||||
/* check and see if the SCRs are in IO space or PCI cfg space */
|
||||
pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
|
||||
if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
|
||||
probe_ent->port_flags |= SIS_FLAG_CFGSCR;
|
||||
pi.flags |= SIS_FLAG_CFGSCR;
|
||||
|
||||
/* if hardware thinks SCRs are in IO space, but there are
|
||||
* no IO resources assigned, change to PCI cfg space.
|
||||
*/
|
||||
if ((!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) &&
|
||||
if ((!(pi.flags & SIS_FLAG_CFGSCR)) &&
|
||||
((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) ||
|
||||
(pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) {
|
||||
genctl &= ~GENCTL_IOMAPPED_SCR;
|
||||
pci_write_config_dword(pdev, SIS_GENCTL, genctl);
|
||||
probe_ent->port_flags |= SIS_FLAG_CFGSCR;
|
||||
pi.flags |= SIS_FLAG_CFGSCR;
|
||||
}
|
||||
|
||||
pci_read_config_byte(pdev, SIS_PMR, &pmr);
|
||||
|
|
@ -306,6 +299,12 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
port2_start = 0x20;
|
||||
}
|
||||
|
||||
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
|
||||
if (!probe_ent) {
|
||||
rc = -ENOMEM;
|
||||
goto err_out_regions;
|
||||
}
|
||||
|
||||
if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
|
||||
probe_ent->port[0].scr_addr =
|
||||
pci_resource_start(pdev, SIS_SCR_PCI_BAR);
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ static int vt6420_prereset(struct ata_port *ap)
|
|||
int online;
|
||||
|
||||
/* don't do any SCR stuff if we're not loading */
|
||||
if (!ATA_PFLAG_LOADING)
|
||||
if (!(ap->pflags & ATA_PFLAG_LOADING))
|
||||
goto skip_scr;
|
||||
|
||||
/* Resume phy. This is the old resume sequence from
|
||||
|
|
|
|||
|
|
@ -2452,8 +2452,8 @@ static int __init amb_module_init (void)
|
|||
static void __exit amb_module_exit (void)
|
||||
{
|
||||
PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module");
|
||||
|
||||
return pci_unregister_driver(&amb_driver);
|
||||
|
||||
pci_unregister_driver(&amb_driver);
|
||||
}
|
||||
|
||||
module_init(amb_module_init);
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,10 @@ static int fs_open(struct atm_vcc *atm_vcc)
|
|||
r = ROUND_UP;
|
||||
}
|
||||
error = make_rate (pcr, r, &tmc0, NULL);
|
||||
if (error) {
|
||||
kfree(tc);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1789,7 +1789,7 @@ static inline void CLOCK_IT (const hrz_dev *dev, u32 ctrl)
|
|||
WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK);
|
||||
}
|
||||
|
||||
static u16 __init read_bia (const hrz_dev * dev, u16 addr)
|
||||
static u16 __devinit read_bia (const hrz_dev * dev, u16 addr)
|
||||
{
|
||||
u32 ctrl = rd_regl (dev, CONTROL_0_REG);
|
||||
|
||||
|
|
@ -2932,8 +2932,8 @@ static int __init hrz_module_init (void) {
|
|||
|
||||
static void __exit hrz_module_exit (void) {
|
||||
PRINTD (DBG_FLOW, "cleanup_module");
|
||||
|
||||
return pci_unregister_driver(&hrz_driver);
|
||||
|
||||
pci_unregister_driver(&hrz_driver);
|
||||
}
|
||||
|
||||
module_init(hrz_module_init);
|
||||
|
|
|
|||
|
|
@ -2759,7 +2759,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
{
|
||||
ns_dev *card;
|
||||
pool_levels pl;
|
||||
int btype;
|
||||
long btype;
|
||||
unsigned long flags;
|
||||
|
||||
card = dev->dev_data;
|
||||
|
|
@ -2859,7 +2859,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
case NS_ADJBUFLEV:
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
btype = (int) arg; /* an int is the same size as a pointer */
|
||||
btype = (long) arg; /* a long is the same size as a pointer or bigger */
|
||||
switch (btype)
|
||||
{
|
||||
case NS_BUFTYPE_SMALL:
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ config DEBUG_DRIVER
|
|||
|
||||
If you are unsure about this, say N here.
|
||||
|
||||
endmenu
|
||||
|
||||
config SYS_HYPERVISOR
|
||||
bool
|
||||
default n
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -372,19 +372,30 @@ int bus_add_device(struct device * dev)
|
|||
pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
|
||||
error = device_add_attrs(bus, dev);
|
||||
if (error)
|
||||
goto out;
|
||||
goto out_put;
|
||||
error = sysfs_create_link(&bus->devices.kobj,
|
||||
&dev->kobj, dev->bus_id);
|
||||
if (error)
|
||||
goto out;
|
||||
goto out_id;
|
||||
error = sysfs_create_link(&dev->kobj,
|
||||
&dev->bus->subsys.kset.kobj, "subsystem");
|
||||
if (error)
|
||||
goto out;
|
||||
goto out_subsys;
|
||||
error = sysfs_create_link(&dev->kobj,
|
||||
&dev->bus->subsys.kset.kobj, "bus");
|
||||
if (error)
|
||||
goto out_deprecated;
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
|
||||
out_deprecated:
|
||||
sysfs_remove_link(&dev->kobj, "subsystem");
|
||||
out_subsys:
|
||||
sysfs_remove_link(&bus->devices.kobj, dev->bus_id);
|
||||
out_id:
|
||||
device_remove_attrs(bus, dev);
|
||||
out_put:
|
||||
put_bus(dev->bus);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -428,8 +439,10 @@ void bus_remove_device(struct device * dev)
|
|||
sysfs_remove_link(&dev->kobj, "bus");
|
||||
sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
|
||||
device_remove_attrs(dev->bus, dev);
|
||||
dev->is_registered = 0;
|
||||
klist_del(&dev->knode_bus);
|
||||
if (dev->is_registered) {
|
||||
dev->is_registered = 0;
|
||||
klist_del(&dev->knode_bus);
|
||||
}
|
||||
pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
|
||||
device_release_driver(dev);
|
||||
put_bus(dev->bus);
|
||||
|
|
@ -505,34 +518,36 @@ int bus_add_driver(struct device_driver *drv)
|
|||
struct bus_type * bus = get_bus(drv->bus);
|
||||
int error = 0;
|
||||
|
||||
if (bus) {
|
||||
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
|
||||
error = kobject_set_name(&drv->kobj, "%s", drv->name);
|
||||
if (error)
|
||||
goto out_put_bus;
|
||||
drv->kobj.kset = &bus->drivers;
|
||||
if ((error = kobject_register(&drv->kobj)))
|
||||
goto out_put_bus;
|
||||
if (!bus)
|
||||
return 0;
|
||||
|
||||
error = driver_attach(drv);
|
||||
if (error)
|
||||
goto out_unregister;
|
||||
klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
|
||||
module_add_driver(drv->owner, drv);
|
||||
pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
|
||||
error = kobject_set_name(&drv->kobj, "%s", drv->name);
|
||||
if (error)
|
||||
goto out_put_bus;
|
||||
drv->kobj.kset = &bus->drivers;
|
||||
if ((error = kobject_register(&drv->kobj)))
|
||||
goto out_put_bus;
|
||||
|
||||
error = driver_add_attrs(bus, drv);
|
||||
if (error) {
|
||||
/* How the hell do we get out of this pickle? Give up */
|
||||
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
|
||||
__FUNCTION__, drv->name);
|
||||
}
|
||||
error = add_bind_files(drv);
|
||||
if (error) {
|
||||
/* Ditto */
|
||||
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
|
||||
__FUNCTION__, drv->name);
|
||||
}
|
||||
error = driver_attach(drv);
|
||||
if (error)
|
||||
goto out_unregister;
|
||||
klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
|
||||
module_add_driver(drv->owner, drv);
|
||||
|
||||
error = driver_add_attrs(bus, drv);
|
||||
if (error) {
|
||||
/* How the hell do we get out of this pickle? Give up */
|
||||
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
|
||||
__FUNCTION__, drv->name);
|
||||
}
|
||||
error = add_bind_files(drv);
|
||||
if (error) {
|
||||
/* Ditto */
|
||||
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
|
||||
__FUNCTION__, drv->name);
|
||||
}
|
||||
|
||||
return error;
|
||||
out_unregister:
|
||||
kobject_unregister(&drv->kobj);
|
||||
|
|
@ -552,16 +567,17 @@ out_put_bus:
|
|||
|
||||
void bus_remove_driver(struct device_driver * drv)
|
||||
{
|
||||
if (drv->bus) {
|
||||
remove_bind_files(drv);
|
||||
driver_remove_attrs(drv->bus, drv);
|
||||
klist_remove(&drv->knode_bus);
|
||||
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
|
||||
driver_detach(drv);
|
||||
module_remove_driver(drv);
|
||||
kobject_unregister(&drv->kobj);
|
||||
put_bus(drv->bus);
|
||||
}
|
||||
if (!drv->bus)
|
||||
return;
|
||||
|
||||
remove_bind_files(drv);
|
||||
driver_remove_attrs(drv->bus, drv);
|
||||
klist_remove(&drv->knode_bus);
|
||||
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
|
||||
driver_detach(drv);
|
||||
module_remove_driver(drv);
|
||||
kobject_unregister(&drv->kobj);
|
||||
put_bus(drv->bus);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -732,11 +748,15 @@ int bus_register(struct bus_type * bus)
|
|||
|
||||
klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
|
||||
klist_init(&bus->klist_drivers, NULL, NULL);
|
||||
bus_add_attrs(bus);
|
||||
retval = bus_add_attrs(bus);
|
||||
if (retval)
|
||||
goto bus_attrs_fail;
|
||||
|
||||
pr_debug("bus type '%s' registered\n", bus->name);
|
||||
return 0;
|
||||
|
||||
bus_attrs_fail:
|
||||
kset_unregister(&bus->drivers);
|
||||
bus_drivers_fail:
|
||||
kset_unregister(&bus->devices);
|
||||
bus_devices_fail:
|
||||
|
|
|
|||
|
|
@ -562,7 +562,10 @@ int class_device_add(struct class_device *class_dev)
|
|||
goto out2;
|
||||
|
||||
/* add the needed attributes to this device */
|
||||
sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem");
|
||||
error = sysfs_create_link(&class_dev->kobj,
|
||||
&parent_class->subsys.kset.kobj, "subsystem");
|
||||
if (error)
|
||||
goto out3;
|
||||
class_dev->uevent_attr.attr.name = "uevent";
|
||||
class_dev->uevent_attr.attr.mode = S_IWUSR;
|
||||
class_dev->uevent_attr.attr.owner = parent_class->owner;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const char *dev_driver_string(struct device *dev)
|
|||
return dev->driver ? dev->driver->name :
|
||||
(dev->bus ? dev->bus->name : "");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_driver_string);
|
||||
EXPORT_SYMBOL(dev_driver_string);
|
||||
|
||||
#define to_dev(obj) container_of(obj, struct device, kobj)
|
||||
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
|
||||
|
|
@ -433,14 +433,16 @@ int device_add(struct device *dev)
|
|||
if (dev->driver)
|
||||
dev->uevent_attr.attr.owner = dev->driver->owner;
|
||||
dev->uevent_attr.store = store_uevent;
|
||||
device_create_file(dev, &dev->uevent_attr);
|
||||
error = device_create_file(dev, &dev->uevent_attr);
|
||||
if (error)
|
||||
goto attrError;
|
||||
|
||||
if (MAJOR(dev->devt)) {
|
||||
struct device_attribute *attr;
|
||||
attr = kzalloc(sizeof(*attr), GFP_KERNEL);
|
||||
if (!attr) {
|
||||
error = -ENOMEM;
|
||||
goto PMError;
|
||||
goto ueventattrError;
|
||||
}
|
||||
attr->attr.name = "dev";
|
||||
attr->attr.mode = S_IRUGO;
|
||||
|
|
@ -450,7 +452,7 @@ int device_add(struct device *dev)
|
|||
error = device_create_file(dev, attr);
|
||||
if (error) {
|
||||
kfree(attr);
|
||||
goto attrError;
|
||||
goto ueventattrError;
|
||||
}
|
||||
|
||||
dev->devt_attr = attr;
|
||||
|
|
@ -477,7 +479,8 @@ int device_add(struct device *dev)
|
|||
if ((error = bus_add_device(dev)))
|
||||
goto BusError;
|
||||
kobject_uevent(&dev->kobj, KOBJ_ADD);
|
||||
bus_attach_device(dev);
|
||||
if ((error = bus_attach_device(dev)))
|
||||
goto AttachError;
|
||||
if (parent)
|
||||
klist_add_tail(&dev->knode_parent, &parent->klist_children);
|
||||
|
||||
|
|
@ -496,6 +499,8 @@ int device_add(struct device *dev)
|
|||
kfree(class_name);
|
||||
put_device(dev);
|
||||
return error;
|
||||
AttachError:
|
||||
bus_remove_device(dev);
|
||||
BusError:
|
||||
device_pm_remove(dev);
|
||||
PMError:
|
||||
|
|
@ -507,6 +512,8 @@ int device_add(struct device *dev)
|
|||
device_remove_file(dev, dev->devt_attr);
|
||||
kfree(dev->devt_attr);
|
||||
}
|
||||
ueventattrError:
|
||||
device_remove_file(dev, &dev->uevent_attr);
|
||||
attrError:
|
||||
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
|
||||
kobject_del(&dev->kobj);
|
||||
|
|
@ -805,8 +812,10 @@ int device_rename(struct device *dev, char *new_name)
|
|||
|
||||
if (dev->class) {
|
||||
old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
|
||||
if (!old_symlink_name)
|
||||
return -ENOMEM;
|
||||
if (!old_symlink_name) {
|
||||
error = -ENOMEM;
|
||||
goto out_free_old_class;
|
||||
}
|
||||
strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
|
||||
}
|
||||
|
||||
|
|
@ -830,9 +839,10 @@ int device_rename(struct device *dev, char *new_name)
|
|||
}
|
||||
put_device(dev);
|
||||
|
||||
kfree(old_class_name);
|
||||
kfree(new_class_name);
|
||||
kfree(old_symlink_name);
|
||||
out_free_old_class:
|
||||
kfree(old_class_name);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include "base.h"
|
||||
#include "power/power.h"
|
||||
|
|
@ -70,6 +71,8 @@ struct stupid_thread_structure {
|
|||
};
|
||||
|
||||
static atomic_t probe_count = ATOMIC_INIT(0);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
|
||||
|
||||
static int really_probe(void *void_data)
|
||||
{
|
||||
struct stupid_thread_structure *data = void_data;
|
||||
|
|
@ -121,6 +124,7 @@ probe_failed:
|
|||
done:
|
||||
kfree(data);
|
||||
atomic_dec(&probe_count);
|
||||
wake_up(&probe_waitqueue);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -171,6 +175,8 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
|
|||
drv->bus->name, dev->bus_id, drv->name);
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
data->drv = drv;
|
||||
data->dev = dev;
|
||||
|
||||
|
|
@ -178,7 +184,7 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
|
|||
probe_task = kthread_run(really_probe, data,
|
||||
"probe-%s", dev->bus_id);
|
||||
if (IS_ERR(probe_task))
|
||||
ret = PTR_ERR(probe_task);
|
||||
ret = really_probe(data);
|
||||
} else
|
||||
ret = really_probe(data);
|
||||
|
||||
|
|
@ -335,6 +341,32 @@ void driver_detach(struct device_driver * drv)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_MULTITHREAD_PROBE
|
||||
static int __init wait_for_probes(void)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__,
|
||||
atomic_read(&probe_count));
|
||||
if (!atomic_read(&probe_count))
|
||||
return 0;
|
||||
while (atomic_read(&probe_count)) {
|
||||
prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE);
|
||||
if (atomic_read(&probe_count))
|
||||
schedule();
|
||||
}
|
||||
finish_wait(&probe_waitqueue, &wait);
|
||||
return 0;
|
||||
}
|
||||
|
||||
core_initcall_sync(wait_for_probes);
|
||||
postcore_initcall_sync(wait_for_probes);
|
||||
arch_initcall_sync(wait_for_probes);
|
||||
subsys_initcall_sync(wait_for_probes);
|
||||
fs_initcall_sync(wait_for_probes);
|
||||
device_initcall_sync(wait_for_probes);
|
||||
late_initcall_sync(wait_for_probes);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL_GPL(device_bind_driver);
|
||||
EXPORT_SYMBOL_GPL(device_release_driver);
|
||||
|
|
|
|||
|
|
@ -141,11 +141,20 @@ dma_pool_create (const char *name, struct device *dev,
|
|||
init_waitqueue_head (&retval->waitq);
|
||||
|
||||
if (dev) {
|
||||
int ret;
|
||||
|
||||
down (&pools_lock);
|
||||
if (list_empty (&dev->dma_pools))
|
||||
device_create_file (dev, &dev_attr_pools);
|
||||
ret = device_create_file (dev, &dev_attr_pools);
|
||||
else
|
||||
ret = 0;
|
||||
/* note: not currently insisting "name" be unique */
|
||||
list_add (&retval->pools, &dev->dma_pools);
|
||||
if (!ret)
|
||||
list_add (&retval->pools, &dev->dma_pools);
|
||||
else {
|
||||
kfree(retval);
|
||||
retval = NULL;
|
||||
}
|
||||
up (&pools_lock);
|
||||
} else
|
||||
INIT_LIST_HEAD (&retval->pools);
|
||||
|
|
|
|||
|
|
@ -97,8 +97,7 @@ static struct attribute_group topology_attr_group = {
|
|||
/* Add/Remove cpu_topology interface for CPU device */
|
||||
static int __cpuinit topology_add_dev(struct sys_device * sys_dev)
|
||||
{
|
||||
sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
|
||||
return 0;
|
||||
return sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
|
||||
}
|
||||
|
||||
static int __cpuinit topology_remove_dev(struct sys_device * sys_dev)
|
||||
|
|
|
|||
|
|
@ -4379,8 +4379,8 @@ static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry)
|
|||
static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState)
|
||||
{
|
||||
memcpy(DeviceState + 2, DeviceState + 3, 1);
|
||||
memcpy(DeviceState + 4, DeviceState + 5, 2);
|
||||
memcpy(DeviceState + 6, DeviceState + 8, 4);
|
||||
memmove(DeviceState + 4, DeviceState + 5, 2);
|
||||
memmove(DeviceState + 6, DeviceState + 8, 4);
|
||||
}
|
||||
|
||||
static inline
|
||||
|
|
|
|||
|
|
@ -1709,10 +1709,13 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
|
|||
return get_disk(unit[drive].gendisk);
|
||||
}
|
||||
|
||||
int __init amiga_floppy_init(void)
|
||||
static int __init amiga_floppy_init(void)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (!MACH_IS_AMIGA)
|
||||
return -ENXIO;
|
||||
|
||||
if (!AMIGAHW_PRESENT(AMI_FLOPPY))
|
||||
return -ENXIO;
|
||||
|
||||
|
|
@ -1809,15 +1812,9 @@ out_blkdev:
|
|||
return ret;
|
||||
}
|
||||
|
||||
module_init(amiga_floppy_init);
|
||||
#ifdef MODULE
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
if (!MACH_IS_AMIGA)
|
||||
return -ENXIO;
|
||||
return amiga_floppy_init();
|
||||
}
|
||||
|
||||
#if 0 /* not safe to unload */
|
||||
void cleanup_module(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
|
||||
#define VERSION "22"
|
||||
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
|
||||
#define VERSION "32"
|
||||
#define AOE_MAJOR 152
|
||||
#define DEVICE_NAME "aoe"
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ struct aoe_atahdr {
|
|||
struct aoe_cfghdr {
|
||||
__be16 bufcnt;
|
||||
__be16 fwver;
|
||||
unsigned char res;
|
||||
unsigned char scnt;
|
||||
unsigned char aoeccmd;
|
||||
unsigned char cslen[2];
|
||||
};
|
||||
|
|
@ -78,12 +78,14 @@ enum {
|
|||
DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */
|
||||
DEVFL_PAUSE = (1<<5),
|
||||
DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */
|
||||
DEVFL_MAXBCNT = (1<<7), /* d->maxbcnt is not changeable */
|
||||
DEVFL_KICKME = (1<<8),
|
||||
|
||||
BUFFL_FAIL = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
MAXATADATA = 1024,
|
||||
DEFAULTBCNT = 2 * 512, /* 2 sectors */
|
||||
NPERSHELF = 16, /* number of slots per shelf address */
|
||||
FREETAG = -1,
|
||||
MIN_BUFS = 8,
|
||||
|
|
@ -107,11 +109,9 @@ struct frame {
|
|||
ulong waited;
|
||||
struct buf *buf;
|
||||
char *bufaddr;
|
||||
int writedatalen;
|
||||
int ndata;
|
||||
|
||||
/* largest possible */
|
||||
unsigned char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
|
||||
ulong bcnt;
|
||||
sector_t lba;
|
||||
struct sk_buff *skb;
|
||||
};
|
||||
|
||||
struct aoedev {
|
||||
|
|
@ -121,9 +121,12 @@ struct aoedev {
|
|||
ulong sysminor;
|
||||
ulong aoemajor;
|
||||
ulong aoeminor;
|
||||
ulong nopen; /* (bd_openers isn't available without sleeping) */
|
||||
ulong rttavg; /* round trip average of requests/responses */
|
||||
u16 nopen; /* (bd_openers isn't available without sleeping) */
|
||||
u16 lasttag; /* last tag sent */
|
||||
u16 rttavg; /* round trip average of requests/responses */
|
||||
u16 mintimer;
|
||||
u16 fw_ver; /* version of blade's firmware */
|
||||
u16 maxbcnt;
|
||||
struct work_struct work;/* disk create work struct */
|
||||
struct gendisk *gd;
|
||||
request_queue_t blkq;
|
||||
|
|
@ -137,8 +140,8 @@ struct aoedev {
|
|||
mempool_t *bufpool; /* for deadlock-free Buf allocation */
|
||||
struct list_head bufq; /* queue of bios to work on */
|
||||
struct buf *inprocess; /* the one we're currently working on */
|
||||
ulong lasttag; /* last tag sent */
|
||||
ulong nframes; /* number of frames below */
|
||||
ushort lostjumbo;
|
||||
ushort nframes; /* number of frames below */
|
||||
struct frame *frames;
|
||||
};
|
||||
|
||||
|
|
@ -157,6 +160,7 @@ void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
|
|||
void aoecmd_ata_rsp(struct sk_buff *);
|
||||
void aoecmd_cfg_rsp(struct sk_buff *);
|
||||
void aoecmd_sleepwork(void *vp);
|
||||
struct sk_buff *new_skb(ulong);
|
||||
|
||||
int aoedev_init(void);
|
||||
void aoedev_exit(void);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/*
|
||||
* aoeblk.c
|
||||
* block device routines
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
static kmem_cache_t *buf_pool_cache;
|
||||
|
||||
/* add attributes for our block devices in sysfs */
|
||||
static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
|
||||
{
|
||||
struct aoedev *d = disk->private_data;
|
||||
|
|
@ -64,21 +63,27 @@ static struct disk_attribute disk_attr_fwver = {
|
|||
.show = aoedisk_show_fwver
|
||||
};
|
||||
|
||||
static void
|
||||
static struct attribute *aoe_attrs[] = {
|
||||
&disk_attr_state.attr,
|
||||
&disk_attr_mac.attr,
|
||||
&disk_attr_netif.attr,
|
||||
&disk_attr_fwver.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group attr_group = {
|
||||
.attrs = aoe_attrs,
|
||||
};
|
||||
|
||||
static int
|
||||
aoedisk_add_sysfs(struct aoedev *d)
|
||||
{
|
||||
sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr);
|
||||
sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr);
|
||||
sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr);
|
||||
sysfs_create_file(&d->gd->kobj, &disk_attr_fwver.attr);
|
||||
return sysfs_create_group(&d->gd->kobj, &attr_group);
|
||||
}
|
||||
void
|
||||
aoedisk_rm_sysfs(struct aoedev *d)
|
||||
{
|
||||
sysfs_remove_link(&d->gd->kobj, "state");
|
||||
sysfs_remove_link(&d->gd->kobj, "mac");
|
||||
sysfs_remove_link(&d->gd->kobj, "netif");
|
||||
sysfs_remove_link(&d->gd->kobj, "firmware-version");
|
||||
sysfs_remove_group(&d->gd->kobj, &attr_group);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -132,8 +137,7 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
|
|||
d = bio->bi_bdev->bd_disk->private_data;
|
||||
buf = mempool_alloc(d->bufpool, GFP_NOIO);
|
||||
if (buf == NULL) {
|
||||
printk(KERN_INFO "aoe: aoeblk_make_request: buf allocation "
|
||||
"failure\n");
|
||||
printk(KERN_INFO "aoe: buf allocation failure\n");
|
||||
bio_endio(bio, bio->bi_size, -ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -143,14 +147,15 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
|
|||
buf->bio = bio;
|
||||
buf->resid = bio->bi_size;
|
||||
buf->sector = bio->bi_sector;
|
||||
buf->bv = buf->bio->bi_io_vec;
|
||||
buf->bv = &bio->bi_io_vec[bio->bi_idx];
|
||||
WARN_ON(buf->bv->bv_len == 0);
|
||||
buf->bv_resid = buf->bv->bv_len;
|
||||
buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
|
||||
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
|
||||
if ((d->flags & DEVFL_UP) == 0) {
|
||||
printk(KERN_INFO "aoe: aoeblk_make_request: device %ld.%ld is not up\n",
|
||||
printk(KERN_INFO "aoe: device %ld.%ld is not up\n",
|
||||
d->aoemajor, d->aoeminor);
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
mempool_free(buf, d->bufpool);
|
||||
|
|
@ -176,7 +181,7 @@ aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
|||
struct aoedev *d = bdev->bd_disk->private_data;
|
||||
|
||||
if ((d->flags & DEVFL_UP) == 0) {
|
||||
printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
|
||||
printk(KERN_ERR "aoe: disk not up\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
@ -203,8 +208,8 @@ aoeblk_gdalloc(void *vp)
|
|||
|
||||
gd = alloc_disk(AOE_PARTITIONS);
|
||||
if (gd == NULL) {
|
||||
printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
|
||||
"structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
|
||||
printk(KERN_ERR "aoe: cannot allocate disk structure for %ld.%ld\n",
|
||||
d->aoemajor, d->aoeminor);
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
d->flags &= ~DEVFL_GDALLOC;
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
|
|
@ -213,8 +218,8 @@ aoeblk_gdalloc(void *vp)
|
|||
|
||||
d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache);
|
||||
if (d->bufpool == NULL) {
|
||||
printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool "
|
||||
"for %ld.%ld\n", d->aoemajor, d->aoeminor);
|
||||
printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%ld\n",
|
||||
d->aoemajor, d->aoeminor);
|
||||
put_disk(gd);
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
d->flags &= ~DEVFL_GDALLOC;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/*
|
||||
* aoechr.c
|
||||
* AoE character device driver
|
||||
|
|
@ -15,7 +15,6 @@ enum {
|
|||
MINOR_INTERFACES,
|
||||
MINOR_REVALIDATE,
|
||||
MSGSZ = 2048,
|
||||
NARGS = 10,
|
||||
NMSG = 100, /* message backlog to retain */
|
||||
};
|
||||
|
||||
|
|
@ -56,9 +55,8 @@ static int
|
|||
interfaces(const char __user *str, size_t size)
|
||||
{
|
||||
if (set_aoe_iflist(str, size)) {
|
||||
printk(KERN_CRIT
|
||||
"%s: could not set interface list: %s\n",
|
||||
__FUNCTION__, "too many interfaces");
|
||||
printk(KERN_ERR
|
||||
"aoe: could not set interface list: too many interfaces\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -81,8 +79,7 @@ revalidate(const char __user *str, size_t size)
|
|||
/* should be e%d.%d format */
|
||||
n = sscanf(buf, "e%d.%d", &major, &minor);
|
||||
if (n != 2) {
|
||||
printk(KERN_ERR "aoe: %s: invalid device specification\n",
|
||||
__FUNCTION__);
|
||||
printk(KERN_ERR "aoe: invalid device specification\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
d = aoedev_by_aoeaddr(major, minor);
|
||||
|
|
@ -90,6 +87,7 @@ revalidate(const char __user *str, size_t size)
|
|||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
d->flags &= ~DEVFL_MAXBCNT;
|
||||
d->flags |= DEVFL_PAUSE;
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
aoecmd_cfg(major, minor);
|
||||
|
|
@ -116,7 +114,7 @@ bail: spin_unlock_irqrestore(&emsgs_lock, flags);
|
|||
|
||||
mp = kmalloc(n, GFP_ATOMIC);
|
||||
if (mp == NULL) {
|
||||
printk(KERN_CRIT "aoe: aoechr_error: allocation failure, len=%ld\n", n);
|
||||
printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +139,7 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp
|
|||
|
||||
switch ((unsigned long) filp->private_data) {
|
||||
default:
|
||||
printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n");
|
||||
printk(KERN_INFO "aoe: can't write to that file.\n");
|
||||
break;
|
||||
case MINOR_DISCOVER:
|
||||
ret = discover();
|
||||
|
|
@ -250,7 +248,7 @@ aoechr_init(void)
|
|||
|
||||
n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops);
|
||||
if (n < 0) {
|
||||
printk(KERN_ERR "aoe: aoechr_init: can't register char device\n");
|
||||
printk(KERN_ERR "aoe: can't register char device\n");
|
||||
return n;
|
||||
}
|
||||
sema_init(&emsgs_sema, 0);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/*
|
||||
* aoecmd.c
|
||||
* Filesystem request handling methods
|
||||
|
|
@ -15,17 +15,19 @@
|
|||
#define TIMERTICK (HZ / 10)
|
||||
#define MINTIMER (2 * TIMERTICK)
|
||||
#define MAXTIMER (HZ << 1)
|
||||
#define MAXWAIT (60 * 3) /* After MAXWAIT seconds, give up and fail dev */
|
||||
|
||||
static struct sk_buff *
|
||||
new_skb(struct net_device *if_dev, ulong len)
|
||||
static int aoe_deadsecs = 60 * 3;
|
||||
module_param(aoe_deadsecs, int, 0644);
|
||||
MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev.");
|
||||
|
||||
struct sk_buff *
|
||||
new_skb(ulong len)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = alloc_skb(len, GFP_ATOMIC);
|
||||
if (skb) {
|
||||
skb->nh.raw = skb->mac.raw = skb->data;
|
||||
skb->dev = if_dev;
|
||||
skb->protocol = __constant_htons(ETH_P_AOE);
|
||||
skb->priority = 0;
|
||||
skb_put(skb, len);
|
||||
|
|
@ -40,29 +42,6 @@ new_skb(struct net_device *if_dev, ulong len)
|
|||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
skb_prepare(struct aoedev *d, struct frame *f)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
char *p;
|
||||
|
||||
skb = new_skb(d->ifp, f->ndata + f->writedatalen);
|
||||
if (!skb) {
|
||||
printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = skb->mac.raw;
|
||||
memcpy(p, f->data, f->ndata);
|
||||
|
||||
if (f->writedatalen) {
|
||||
p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
|
||||
memcpy(p, f->bufaddr, f->writedatalen);
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct frame *
|
||||
getframe(struct aoedev *d, int tag)
|
||||
{
|
||||
|
|
@ -107,6 +86,17 @@ aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
|
|||
return host_tag;
|
||||
}
|
||||
|
||||
static inline void
|
||||
put_lba(struct aoe_atahdr *ah, sector_t lba)
|
||||
{
|
||||
ah->lba0 = lba;
|
||||
ah->lba1 = lba >>= 8;
|
||||
ah->lba2 = lba >>= 8;
|
||||
ah->lba3 = lba >>= 8;
|
||||
ah->lba4 = lba >>= 8;
|
||||
ah->lba5 = lba >>= 8;
|
||||
}
|
||||
|
||||
static void
|
||||
aoecmd_ata_rw(struct aoedev *d, struct frame *f)
|
||||
{
|
||||
|
|
@ -125,29 +115,27 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
|
|||
|
||||
sector = buf->sector;
|
||||
bcnt = buf->bv_resid;
|
||||
if (bcnt > MAXATADATA)
|
||||
bcnt = MAXATADATA;
|
||||
if (bcnt > d->maxbcnt)
|
||||
bcnt = d->maxbcnt;
|
||||
|
||||
/* initialize the headers & frame */
|
||||
h = (struct aoe_hdr *) f->data;
|
||||
skb = f->skb;
|
||||
h = (struct aoe_hdr *) skb->mac.raw;
|
||||
ah = (struct aoe_atahdr *) (h+1);
|
||||
f->ndata = sizeof *h + sizeof *ah;
|
||||
memset(h, 0, f->ndata);
|
||||
skb->len = sizeof *h + sizeof *ah;
|
||||
memset(h, 0, ETH_ZLEN);
|
||||
f->tag = aoehdr_atainit(d, h);
|
||||
f->waited = 0;
|
||||
f->buf = buf;
|
||||
f->bufaddr = buf->bufaddr;
|
||||
f->bcnt = bcnt;
|
||||
f->lba = sector;
|
||||
|
||||
/* set up ata header */
|
||||
ah->scnt = bcnt >> 9;
|
||||
ah->lba0 = sector;
|
||||
ah->lba1 = sector >>= 8;
|
||||
ah->lba2 = sector >>= 8;
|
||||
ah->lba3 = sector >>= 8;
|
||||
put_lba(ah, sector);
|
||||
if (d->flags & DEVFL_EXT) {
|
||||
ah->aflags |= AOEAFL_EXT;
|
||||
ah->lba4 = sector >>= 8;
|
||||
ah->lba5 = sector >>= 8;
|
||||
} else {
|
||||
extbit = 0;
|
||||
ah->lba3 &= 0x0f;
|
||||
|
|
@ -155,11 +143,14 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
|
|||
}
|
||||
|
||||
if (bio_data_dir(buf->bio) == WRITE) {
|
||||
skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
|
||||
offset_in_page(f->bufaddr), bcnt);
|
||||
ah->aflags |= AOEAFL_WRITE;
|
||||
f->writedatalen = bcnt;
|
||||
skb->len += bcnt;
|
||||
skb->data_len = bcnt;
|
||||
} else {
|
||||
skb->len = ETH_ZLEN;
|
||||
writebit = 0;
|
||||
f->writedatalen = 0;
|
||||
}
|
||||
|
||||
ah->cmdstat = WIN_READ | writebit | extbit;
|
||||
|
|
@ -168,26 +159,27 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
|
|||
buf->nframesout += 1;
|
||||
buf->bufaddr += bcnt;
|
||||
buf->bv_resid -= bcnt;
|
||||
/* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */
|
||||
/* printk(KERN_DEBUG "aoe: bv_resid=%ld\n", buf->bv_resid); */
|
||||
buf->resid -= bcnt;
|
||||
buf->sector += bcnt >> 9;
|
||||
if (buf->resid == 0) {
|
||||
d->inprocess = NULL;
|
||||
} else if (buf->bv_resid == 0) {
|
||||
buf->bv++;
|
||||
WARN_ON(buf->bv->bv_len == 0);
|
||||
buf->bv_resid = buf->bv->bv_len;
|
||||
buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
|
||||
}
|
||||
|
||||
skb = skb_prepare(d, f);
|
||||
if (skb) {
|
||||
skb->next = NULL;
|
||||
if (d->sendq_hd)
|
||||
d->sendq_tl->next = skb;
|
||||
else
|
||||
d->sendq_hd = skb;
|
||||
d->sendq_tl = skb;
|
||||
}
|
||||
skb->dev = d->ifp;
|
||||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
return;
|
||||
if (d->sendq_hd)
|
||||
d->sendq_tl->next = skb;
|
||||
else
|
||||
d->sendq_hd = skb;
|
||||
d->sendq_tl = skb;
|
||||
}
|
||||
|
||||
/* some callers cannot sleep, and they can call this function,
|
||||
|
|
@ -209,11 +201,12 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
|
|||
if (!is_aoe_netif(ifp))
|
||||
continue;
|
||||
|
||||
skb = new_skb(ifp, sizeof *h + sizeof *ch);
|
||||
skb = new_skb(sizeof *h + sizeof *ch);
|
||||
if (skb == NULL) {
|
||||
printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
|
||||
printk(KERN_INFO "aoe: skb alloc failure\n");
|
||||
continue;
|
||||
}
|
||||
skb->dev = ifp;
|
||||
if (sl_tail == NULL)
|
||||
sl_tail = skb;
|
||||
h = (struct aoe_hdr *) skb->mac.raw;
|
||||
|
|
@ -237,6 +230,29 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
|
|||
return sl;
|
||||
}
|
||||
|
||||
static struct frame *
|
||||
freeframe(struct aoedev *d)
|
||||
{
|
||||
struct frame *f, *e;
|
||||
int n = 0;
|
||||
|
||||
f = d->frames;
|
||||
e = f + d->nframes;
|
||||
for (; f<e; f++) {
|
||||
if (f->tag != FREETAG)
|
||||
continue;
|
||||
if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) {
|
||||
skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
|
||||
return f;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
if (n == d->nframes) /* wait for network layer */
|
||||
d->flags |= DEVFL_KICKME;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* enters with d->lock held */
|
||||
void
|
||||
aoecmd_work(struct aoedev *d)
|
||||
|
|
@ -252,7 +268,7 @@ aoecmd_work(struct aoedev *d)
|
|||
}
|
||||
|
||||
loop:
|
||||
f = getframe(d, FREETAG);
|
||||
f = freeframe(d);
|
||||
if (f == NULL)
|
||||
return;
|
||||
if (d->inprocess == NULL) {
|
||||
|
|
@ -260,7 +276,7 @@ loop:
|
|||
return;
|
||||
buf = container_of(d->bufq.next, struct buf, bufs);
|
||||
list_del(d->bufq.next);
|
||||
/*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */
|
||||
/*printk(KERN_DEBUG "aoe: bi_size=%ld\n", buf->bio->bi_size); */
|
||||
d->inprocess = buf;
|
||||
}
|
||||
aoecmd_ata_rw(d, f);
|
||||
|
|
@ -272,6 +288,7 @@ rexmit(struct aoedev *d, struct frame *f)
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
struct aoe_hdr *h;
|
||||
struct aoe_atahdr *ah;
|
||||
char buf[128];
|
||||
u32 n;
|
||||
|
||||
|
|
@ -283,21 +300,41 @@ rexmit(struct aoedev *d, struct frame *f)
|
|||
d->aoemajor, d->aoeminor, f->tag, jiffies, n);
|
||||
aoechr_error(buf);
|
||||
|
||||
h = (struct aoe_hdr *) f->data;
|
||||
skb = f->skb;
|
||||
h = (struct aoe_hdr *) skb->mac.raw;
|
||||
ah = (struct aoe_atahdr *) (h+1);
|
||||
f->tag = n;
|
||||
h->tag = cpu_to_be32(n);
|
||||
memcpy(h->dst, d->addr, sizeof h->dst);
|
||||
memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
|
||||
|
||||
skb = skb_prepare(d, f);
|
||||
if (skb) {
|
||||
skb->next = NULL;
|
||||
if (d->sendq_hd)
|
||||
d->sendq_tl->next = skb;
|
||||
else
|
||||
d->sendq_hd = skb;
|
||||
d->sendq_tl = skb;
|
||||
n = DEFAULTBCNT / 512;
|
||||
if (ah->scnt > n) {
|
||||
ah->scnt = n;
|
||||
if (ah->aflags & AOEAFL_WRITE) {
|
||||
skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
|
||||
offset_in_page(f->bufaddr), DEFAULTBCNT);
|
||||
skb->len = sizeof *h + sizeof *ah + DEFAULTBCNT;
|
||||
skb->data_len = DEFAULTBCNT;
|
||||
}
|
||||
if (++d->lostjumbo > (d->nframes << 1))
|
||||
if (d->maxbcnt != DEFAULTBCNT) {
|
||||
printk(KERN_INFO "aoe: e%ld.%ld: too many lost jumbo on %s - using 1KB frames.\n",
|
||||
d->aoemajor, d->aoeminor, d->ifp->name);
|
||||
d->maxbcnt = DEFAULTBCNT;
|
||||
d->flags |= DEVFL_MAXBCNT;
|
||||
}
|
||||
}
|
||||
|
||||
skb->dev = d->ifp;
|
||||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
return;
|
||||
if (d->sendq_hd)
|
||||
d->sendq_tl->next = skb;
|
||||
else
|
||||
d->sendq_hd = skb;
|
||||
d->sendq_tl = skb;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -340,13 +377,17 @@ rexmit_timer(ulong vp)
|
|||
if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
|
||||
n = f->waited += timeout;
|
||||
n /= HZ;
|
||||
if (n > MAXWAIT) { /* waited too long. device failure. */
|
||||
if (n > aoe_deadsecs) { /* waited too long for response */
|
||||
aoedev_downdev(d);
|
||||
break;
|
||||
}
|
||||
rexmit(d, f);
|
||||
}
|
||||
}
|
||||
if (d->flags & DEVFL_KICKME) {
|
||||
d->flags &= ~DEVFL_KICKME;
|
||||
aoecmd_work(d);
|
||||
}
|
||||
|
||||
sl = d->sendq_hd;
|
||||
d->sendq_hd = d->sendq_tl = NULL;
|
||||
|
|
@ -431,8 +472,8 @@ ataid_complete(struct aoedev *d, unsigned char *id)
|
|||
}
|
||||
|
||||
if (d->ssize != ssize)
|
||||
printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
|
||||
"sectors\n", (unsigned long long)mac_addr(d->addr),
|
||||
printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu sectors\n",
|
||||
(unsigned long long)mac_addr(d->addr),
|
||||
d->aoemajor, d->aoeminor,
|
||||
d->fw_ver, (long long)ssize);
|
||||
d->ssize = ssize;
|
||||
|
|
@ -442,11 +483,9 @@ ataid_complete(struct aoedev *d, unsigned char *id)
|
|||
d->flags |= DEVFL_NEWSIZE;
|
||||
} else {
|
||||
if (d->flags & DEVFL_GDALLOC) {
|
||||
printk(KERN_INFO "aoe: %s: %s e%lu.%lu, %s\n",
|
||||
__FUNCTION__,
|
||||
"can't schedule work for",
|
||||
printk(KERN_ERR "aoe: can't schedule work for e%lu.%lu, %s\n",
|
||||
d->aoemajor, d->aoeminor,
|
||||
"it's already on! (This really shouldn't happen).\n");
|
||||
"it's already on! This shouldn't happen.\n");
|
||||
return;
|
||||
}
|
||||
d->flags |= DEVFL_GDALLOC;
|
||||
|
|
@ -460,8 +499,15 @@ calc_rttavg(struct aoedev *d, int rtt)
|
|||
register long n;
|
||||
|
||||
n = rtt;
|
||||
if (n < MINTIMER)
|
||||
n = MINTIMER;
|
||||
if (n < 0) {
|
||||
n = -rtt;
|
||||
if (n < MINTIMER)
|
||||
n = MINTIMER;
|
||||
else if (n > MAXTIMER)
|
||||
n = MAXTIMER;
|
||||
d->mintimer += (n - d->mintimer) >> 1;
|
||||
} else if (n < d->mintimer)
|
||||
n = d->mintimer;
|
||||
else if (n > MAXTIMER)
|
||||
n = MAXTIMER;
|
||||
|
||||
|
|
@ -474,7 +520,7 @@ void
|
|||
aoecmd_ata_rsp(struct sk_buff *skb)
|
||||
{
|
||||
struct aoedev *d;
|
||||
struct aoe_hdr *hin;
|
||||
struct aoe_hdr *hin, *hout;
|
||||
struct aoe_atahdr *ahin, *ahout;
|
||||
struct frame *f;
|
||||
struct buf *buf;
|
||||
|
|
@ -497,8 +543,10 @@ aoecmd_ata_rsp(struct sk_buff *skb)
|
|||
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
|
||||
f = getframe(d, be32_to_cpu(hin->tag));
|
||||
n = be32_to_cpu(hin->tag);
|
||||
f = getframe(d, n);
|
||||
if (f == NULL) {
|
||||
calc_rttavg(d, -tsince(n));
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
snprintf(ebuf, sizeof ebuf,
|
||||
"%15s e%d.%d tag=%08x@%08lx\n",
|
||||
|
|
@ -514,26 +562,27 @@ aoecmd_ata_rsp(struct sk_buff *skb)
|
|||
calc_rttavg(d, tsince(f->tag));
|
||||
|
||||
ahin = (struct aoe_atahdr *) (hin+1);
|
||||
ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
|
||||
hout = (struct aoe_hdr *) f->skb->mac.raw;
|
||||
ahout = (struct aoe_atahdr *) (hout+1);
|
||||
buf = f->buf;
|
||||
|
||||
if (ahout->cmdstat == WIN_IDENTIFY)
|
||||
d->flags &= ~DEVFL_PAUSE;
|
||||
if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
|
||||
printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
|
||||
"stat=%2.2Xh from e%ld.%ld\n",
|
||||
printk(KERN_ERR
|
||||
"aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%ld\n",
|
||||
ahout->cmdstat, ahin->cmdstat,
|
||||
d->aoemajor, d->aoeminor);
|
||||
if (buf)
|
||||
buf->flags |= BUFFL_FAIL;
|
||||
} else {
|
||||
n = ahout->scnt << 9;
|
||||
switch (ahout->cmdstat) {
|
||||
case WIN_READ:
|
||||
case WIN_READ_EXT:
|
||||
n = ahout->scnt << 9;
|
||||
if (skb->len - sizeof *hin - sizeof *ahin < n) {
|
||||
printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
|
||||
"ata data size in read. skb->len=%d\n",
|
||||
printk(KERN_ERR
|
||||
"aoe: runt data size in read. skb->len=%d\n",
|
||||
skb->len);
|
||||
/* fail frame f? just returning will rexmit. */
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
|
|
@ -542,22 +591,49 @@ aoecmd_ata_rsp(struct sk_buff *skb)
|
|||
memcpy(f->bufaddr, ahin+1, n);
|
||||
case WIN_WRITE:
|
||||
case WIN_WRITE_EXT:
|
||||
if (f->bcnt -= n) {
|
||||
skb = f->skb;
|
||||
f->bufaddr += n;
|
||||
put_lba(ahout, f->lba += ahout->scnt);
|
||||
n = f->bcnt;
|
||||
if (n > DEFAULTBCNT)
|
||||
n = DEFAULTBCNT;
|
||||
ahout->scnt = n >> 9;
|
||||
if (ahout->aflags & AOEAFL_WRITE) {
|
||||
skb_fill_page_desc(skb, 0,
|
||||
virt_to_page(f->bufaddr),
|
||||
offset_in_page(f->bufaddr), n);
|
||||
skb->len = sizeof *hout + sizeof *ahout + n;
|
||||
skb->data_len = n;
|
||||
}
|
||||
f->tag = newtag(d);
|
||||
hout->tag = cpu_to_be32(f->tag);
|
||||
skb->dev = d->ifp;
|
||||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
if (skb)
|
||||
aoenet_xmit(skb);
|
||||
return;
|
||||
}
|
||||
if (n > DEFAULTBCNT)
|
||||
d->lostjumbo = 0;
|
||||
break;
|
||||
case WIN_IDENTIFY:
|
||||
if (skb->len - sizeof *hin - sizeof *ahin < 512) {
|
||||
printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
|
||||
"in ataid. skb->len=%d\n", skb->len);
|
||||
printk(KERN_INFO
|
||||
"aoe: runt data size in ataid. skb->len=%d\n",
|
||||
skb->len);
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
return;
|
||||
}
|
||||
ataid_complete(d, (char *) (ahin+1));
|
||||
break;
|
||||
default:
|
||||
printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
|
||||
"outbound ata command %2.2Xh for %d.%d\n",
|
||||
ahout->cmdstat,
|
||||
be16_to_cpu(hin->major),
|
||||
hin->minor);
|
||||
printk(KERN_INFO
|
||||
"aoe: unrecognized ata command %2.2Xh for %d.%d\n",
|
||||
ahout->cmdstat,
|
||||
be16_to_cpu(hin->major),
|
||||
hin->minor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -612,33 +688,32 @@ aoecmd_ata_id(struct aoedev *d)
|
|||
struct frame *f;
|
||||
struct sk_buff *skb;
|
||||
|
||||
f = getframe(d, FREETAG);
|
||||
f = freeframe(d);
|
||||
if (f == NULL) {
|
||||
printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame. "
|
||||
"This shouldn't happen.\n");
|
||||
printk(KERN_ERR "aoe: can't get a frame. This shouldn't happen.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialize the headers & frame */
|
||||
h = (struct aoe_hdr *) f->data;
|
||||
skb = f->skb;
|
||||
h = (struct aoe_hdr *) skb->mac.raw;
|
||||
ah = (struct aoe_atahdr *) (h+1);
|
||||
f->ndata = sizeof *h + sizeof *ah;
|
||||
memset(h, 0, f->ndata);
|
||||
skb->len = ETH_ZLEN;
|
||||
memset(h, 0, ETH_ZLEN);
|
||||
f->tag = aoehdr_atainit(d, h);
|
||||
f->waited = 0;
|
||||
f->writedatalen = 0;
|
||||
|
||||
/* set up ata header */
|
||||
ah->scnt = 1;
|
||||
ah->cmdstat = WIN_IDENTIFY;
|
||||
ah->lba3 = 0xa0;
|
||||
|
||||
skb = skb_prepare(d, f);
|
||||
skb->dev = d->ifp;
|
||||
|
||||
d->rttavg = MAXTIMER;
|
||||
d->timer.function = rexmit_timer;
|
||||
|
||||
return skb;
|
||||
return skb_clone(skb, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -648,9 +723,9 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
|
|||
struct aoe_hdr *h;
|
||||
struct aoe_cfghdr *ch;
|
||||
ulong flags, sysminor, aoemajor;
|
||||
u16 bufcnt;
|
||||
struct sk_buff *sl;
|
||||
enum { MAXFRAMES = 16 };
|
||||
u16 n;
|
||||
|
||||
h = (struct aoe_hdr *) skb->mac.raw;
|
||||
ch = (struct aoe_cfghdr *) (h+1);
|
||||
|
|
@ -661,26 +736,25 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
|
|||
*/
|
||||
aoemajor = be16_to_cpu(h->major);
|
||||
if (aoemajor == 0xfff) {
|
||||
printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
|
||||
"address is all ones. Check shelf dip switches\n");
|
||||
printk(KERN_ERR "aoe: Warning: shelf address is all ones. "
|
||||
"Check shelf dip switches.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sysminor = SYSMINOR(aoemajor, h->minor);
|
||||
if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
|
||||
printk(KERN_INFO
|
||||
"aoe: e%ld.%d: minor number too large\n",
|
||||
printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n",
|
||||
aoemajor, (int) h->minor);
|
||||
return;
|
||||
}
|
||||
|
||||
bufcnt = be16_to_cpu(ch->bufcnt);
|
||||
if (bufcnt > MAXFRAMES) /* keep it reasonable */
|
||||
bufcnt = MAXFRAMES;
|
||||
n = be16_to_cpu(ch->bufcnt);
|
||||
if (n > MAXFRAMES) /* keep it reasonable */
|
||||
n = MAXFRAMES;
|
||||
|
||||
d = aoedev_by_sysminor_m(sysminor, bufcnt);
|
||||
d = aoedev_by_sysminor_m(sysminor, n);
|
||||
if (d == NULL) {
|
||||
printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n");
|
||||
printk(KERN_INFO "aoe: device sysminor_m failure\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -689,6 +763,20 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
|
|||
/* permit device to migrate mac and network interface */
|
||||
d->ifp = skb->dev;
|
||||
memcpy(d->addr, h->src, sizeof d->addr);
|
||||
if (!(d->flags & DEVFL_MAXBCNT)) {
|
||||
n = d->ifp->mtu;
|
||||
n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr);
|
||||
n /= 512;
|
||||
if (n > ch->scnt)
|
||||
n = ch->scnt;
|
||||
n = n ? n * 512 : DEFAULTBCNT;
|
||||
if (n != d->maxbcnt) {
|
||||
printk(KERN_INFO
|
||||
"aoe: e%ld.%ld: setting %d byte data frames on %s\n",
|
||||
d->aoemajor, d->aoeminor, n, d->ifp->name);
|
||||
d->maxbcnt = n;
|
||||
}
|
||||
}
|
||||
|
||||
/* don't change users' perspective */
|
||||
if (d->nopen && !(d->flags & DEVFL_PAUSE)) {
|
||||
|
|
@ -696,6 +784,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
|
|||
return;
|
||||
}
|
||||
d->flags |= DEVFL_PAUSE; /* force pause */
|
||||
d->mintimer = MINTIMER;
|
||||
d->fw_ver = be16_to_cpu(ch->fwver);
|
||||
|
||||
/* check for already outstanding ataid */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/*
|
||||
* aoedev.c
|
||||
* AoE device utility functions; maintains device list.
|
||||
|
|
@ -20,11 +20,8 @@ aoedev_isbusy(struct aoedev *d)
|
|||
f = d->frames;
|
||||
e = f + d->nframes;
|
||||
do {
|
||||
if (f->tag != FREETAG) {
|
||||
printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n",
|
||||
d->aoemajor, d->aoeminor);
|
||||
if (f->tag != FREETAG)
|
||||
return 1;
|
||||
}
|
||||
} while (++f < e);
|
||||
|
||||
return 0;
|
||||
|
|
@ -66,22 +63,32 @@ aoedev_newdev(ulong nframes)
|
|||
struct frame *f, *e;
|
||||
|
||||
d = kzalloc(sizeof *d, GFP_ATOMIC);
|
||||
if (d == NULL)
|
||||
return NULL;
|
||||
f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
|
||||
if (f == NULL) {
|
||||
kfree(d);
|
||||
switch (!d || !f) {
|
||||
case 0:
|
||||
d->nframes = nframes;
|
||||
d->frames = f;
|
||||
e = f + nframes;
|
||||
for (; f<e; f++) {
|
||||
f->tag = FREETAG;
|
||||
f->skb = new_skb(ETH_ZLEN);
|
||||
if (!f->skb)
|
||||
break;
|
||||
}
|
||||
if (f == e)
|
||||
break;
|
||||
while (f > d->frames) {
|
||||
f--;
|
||||
dev_kfree_skb(f->skb);
|
||||
}
|
||||
default:
|
||||
if (f)
|
||||
kfree(f);
|
||||
if (d)
|
||||
kfree(d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_WORK(&d->work, aoecmd_sleepwork, d);
|
||||
|
||||
d->nframes = nframes;
|
||||
d->frames = f;
|
||||
e = f + nframes;
|
||||
for (; f<e; f++)
|
||||
f->tag = FREETAG;
|
||||
|
||||
spin_lock_init(&d->lock);
|
||||
init_timer(&d->timer);
|
||||
d->timer.data = (ulong) d;
|
||||
|
|
@ -114,6 +121,7 @@ aoedev_downdev(struct aoedev *d)
|
|||
mempool_free(buf, d->bufpool);
|
||||
bio_endio(bio, bio->bi_size, -EIO);
|
||||
}
|
||||
skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
|
||||
}
|
||||
d->inprocess = NULL;
|
||||
|
||||
|
|
@ -148,7 +156,7 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
|
|||
d = aoedev_newdev(bufcnt);
|
||||
if (d == NULL) {
|
||||
spin_unlock_irqrestore(&devlist_lock, flags);
|
||||
printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
|
||||
printk(KERN_INFO "aoe: aoedev_newdev failure.\n");
|
||||
return NULL;
|
||||
}
|
||||
d->sysminor = sysminor;
|
||||
|
|
@ -163,11 +171,19 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
|
|||
static void
|
||||
aoedev_freedev(struct aoedev *d)
|
||||
{
|
||||
struct frame *f, *e;
|
||||
|
||||
if (d->gd) {
|
||||
aoedisk_rm_sysfs(d);
|
||||
del_gendisk(d->gd);
|
||||
put_disk(d->gd);
|
||||
}
|
||||
f = d->frames;
|
||||
e = f + d->nframes;
|
||||
for (; f<e; f++) {
|
||||
skb_shinfo(f->skb)->nr_frags = 0;
|
||||
dev_kfree_skb(f->skb);
|
||||
}
|
||||
kfree(d->frames);
|
||||
if (d->bufpool)
|
||||
mempool_destroy(d->bufpool);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/*
|
||||
* aoemain.c
|
||||
* Module initialization routines, discover timer
|
||||
|
|
@ -84,13 +84,11 @@ aoe_init(void)
|
|||
goto net_fail;
|
||||
ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "aoe: aoeblk_init: can't register major\n");
|
||||
printk(KERN_ERR "aoe: can't register major\n");
|
||||
goto blkreg_fail;
|
||||
}
|
||||
|
||||
printk(KERN_INFO
|
||||
"aoe: aoe_init: AoE v%s initialised.\n",
|
||||
VERSION);
|
||||
printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
|
||||
discover_timer(TINIT);
|
||||
return 0;
|
||||
|
||||
|
|
@ -103,7 +101,7 @@ aoe_init(void)
|
|||
chr_fail:
|
||||
aoedev_exit();
|
||||
|
||||
printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
|
||||
printk(KERN_INFO "aoe: initialisation failure.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
|
||||
/*
|
||||
* aoenet.c
|
||||
* Ethernet portion of AoE driver
|
||||
|
|
@ -74,7 +74,7 @@ set_aoe_iflist(const char __user *user_str, size_t size)
|
|||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(aoe_iflist, user_str, size)) {
|
||||
printk(KERN_INFO "aoe: %s: copy from user failed\n", __FUNCTION__);
|
||||
printk(KERN_INFO "aoe: copy from user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
aoe_iflist[size] = 0x00;
|
||||
|
|
@ -132,8 +132,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
|
|||
if (n > NECODES)
|
||||
n = 0;
|
||||
if (net_ratelimit())
|
||||
printk(KERN_ERR "aoe: aoenet_rcv: error packet from %d.%d; "
|
||||
"ecode=%d '%s'\n",
|
||||
printk(KERN_ERR "aoe: error packet from %d.%d; ecode=%d '%s'\n",
|
||||
be16_to_cpu(h->major), h->minor,
|
||||
h->err, aoe_errlist[n]);
|
||||
goto exit;
|
||||
|
|
@ -147,7 +146,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
|
|||
aoecmd_cfg_rsp(skb);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_INFO "aoe: aoenet_rcv: unknown cmd %d\n", h->cmd);
|
||||
printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
|
||||
}
|
||||
exit:
|
||||
dev_kfree_skb(skb);
|
||||
|
|
|
|||
|
|
@ -1300,6 +1300,12 @@ static void cciss_softirq_done(struct request *rq)
|
|||
|
||||
complete_buffers(rq->bio, rq->errors);
|
||||
|
||||
if (blk_fs_request(rq)) {
|
||||
const int rw = rq_data_dir(rq);
|
||||
|
||||
disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
|
||||
}
|
||||
|
||||
#ifdef CCISS_DEBUG
|
||||
printk("Done with %p\n", rq);
|
||||
#endif /* CCISS_DEBUG */
|
||||
|
|
@ -1923,7 +1929,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
|
|||
{
|
||||
int return_code;
|
||||
unsigned long t;
|
||||
unsigned long rem;
|
||||
|
||||
memset(inq_buff, 0, sizeof(InquiryData_struct));
|
||||
if (withirq)
|
||||
|
|
@ -1939,26 +1944,23 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
|
|||
printk(KERN_WARNING
|
||||
"cciss: reading geometry failed, volume "
|
||||
"does not support reading geometry\n");
|
||||
drv->block_size = block_size;
|
||||
drv->nr_blocks = total_size;
|
||||
drv->heads = 255;
|
||||
drv->sectors = 32; // Sectors per track
|
||||
t = drv->heads * drv->sectors;
|
||||
drv->cylinders = total_size;
|
||||
rem = do_div(drv->cylinders, t);
|
||||
} else {
|
||||
drv->block_size = block_size;
|
||||
drv->nr_blocks = total_size;
|
||||
drv->heads = inq_buff->data_byte[6];
|
||||
drv->sectors = inq_buff->data_byte[7];
|
||||
drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8;
|
||||
drv->cylinders += inq_buff->data_byte[5];
|
||||
drv->raid_level = inq_buff->data_byte[8];
|
||||
t = drv->heads * drv->sectors;
|
||||
if (t > 1) {
|
||||
drv->cylinders = total_size;
|
||||
rem = do_div(drv->cylinders, t);
|
||||
}
|
||||
}
|
||||
drv->block_size = block_size;
|
||||
drv->nr_blocks = total_size;
|
||||
t = drv->heads * drv->sectors;
|
||||
if (t > 1) {
|
||||
unsigned rem = sector_div(total_size, t);
|
||||
if (rem)
|
||||
total_size++;
|
||||
drv->cylinders = total_size;
|
||||
}
|
||||
} else { /* Get geometry failed */
|
||||
printk(KERN_WARNING "cciss: reading geometry failed\n");
|
||||
|
|
@ -1996,8 +1998,8 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
|
|||
*block_size = BLOCK_SIZE;
|
||||
}
|
||||
if (*total_size != (__u32) 0)
|
||||
printk(KERN_INFO " blocks= %lld block_size= %d\n",
|
||||
*total_size, *block_size);
|
||||
printk(KERN_INFO " blocks= %llu block_size= %d\n",
|
||||
(unsigned long long)*total_size, *block_size);
|
||||
kfree(buf);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2031,8 +2033,8 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size,
|
|||
*total_size = 0;
|
||||
*block_size = BLOCK_SIZE;
|
||||
}
|
||||
printk(KERN_INFO " blocks= %lld block_size= %d\n",
|
||||
*total_size, *block_size);
|
||||
printk(KERN_INFO " blocks= %llu block_size= %d\n",
|
||||
(unsigned long long)*total_size, *block_size);
|
||||
kfree(buf);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -998,6 +998,7 @@ static inline void complete_buffers(struct bio *bio, int ok)
|
|||
*/
|
||||
static inline void complete_command(cmdlist_t *cmd, int timeout)
|
||||
{
|
||||
struct request *rq = cmd->rq;
|
||||
int ok=1;
|
||||
int i, ddir;
|
||||
|
||||
|
|
@ -1029,12 +1030,18 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
|
|||
pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
|
||||
cmd->req.sg[i].size, ddir);
|
||||
|
||||
complete_buffers(cmd->rq->bio, ok);
|
||||
complete_buffers(rq->bio, ok);
|
||||
|
||||
add_disk_randomness(cmd->rq->rq_disk);
|
||||
if (blk_fs_request(rq)) {
|
||||
const int rw = rq_data_dir(rq);
|
||||
|
||||
DBGPX(printk("Done with %p\n", cmd->rq););
|
||||
end_that_request_last(cmd->rq, ok ? 1 : -EIO);
|
||||
disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
|
||||
}
|
||||
|
||||
add_disk_randomness(rq->rq_disk);
|
||||
|
||||
DBGPX(printk("Done with %p\n", rq););
|
||||
end_that_request_last(rq, ok ? 1 : -EIO);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -432,6 +432,12 @@ static int __init rd_init(void)
|
|||
rd_disks[i] = alloc_disk(1);
|
||||
if (!rd_disks[i])
|
||||
goto out;
|
||||
|
||||
rd_queue[i] = blk_alloc_queue(GFP_KERNEL);
|
||||
if (!rd_queue[i]) {
|
||||
put_disk(rd_disks[i]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) {
|
||||
|
|
@ -442,10 +448,6 @@ static int __init rd_init(void)
|
|||
for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) {
|
||||
struct gendisk *disk = rd_disks[i];
|
||||
|
||||
rd_queue[i] = blk_alloc_queue(GFP_KERNEL);
|
||||
if (!rd_queue[i])
|
||||
goto out_queue;
|
||||
|
||||
blk_queue_make_request(rd_queue[i], &rd_make_request);
|
||||
blk_queue_hardsect_size(rd_queue[i], rd_blocksize);
|
||||
|
||||
|
|
@ -466,8 +468,6 @@ static int __init rd_init(void)
|
|||
CONFIG_BLK_DEV_RAM_COUNT, rd_size, rd_blocksize);
|
||||
|
||||
return 0;
|
||||
out_queue:
|
||||
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
|
||||
out:
|
||||
while (i--) {
|
||||
put_disk(rd_disks[i]);
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
#include <linux/blkdev.h>
|
||||
#include <linux/blkpg.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/dma.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ static struct kobject *z2_find(dev_t dev, int *part, void *data)
|
|||
|
||||
static struct request_queue *z2_queue;
|
||||
|
||||
int __init
|
||||
static int __init
|
||||
z2_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -370,26 +370,7 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MODULE)
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
int
|
||||
init_module( void )
|
||||
{
|
||||
int error;
|
||||
|
||||
error = z2_init();
|
||||
if ( error == 0 )
|
||||
{
|
||||
printk( KERN_INFO DEVICE_NAME ": loaded as module\n" );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
cleanup_module( void )
|
||||
static void __exit z2_exit(void)
|
||||
{
|
||||
int i, j;
|
||||
blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256);
|
||||
|
|
@ -425,4 +406,7 @@ cleanup_module( void )
|
|||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
module_init(z2_init);
|
||||
module_exit(z2_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/firmware.h>
|
||||
|
|
@ -43,7 +42,7 @@
|
|||
#define BT_DBG(D...)
|
||||
#endif
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define VERSION "1.1"
|
||||
|
||||
static int ignore = 0;
|
||||
|
||||
|
|
@ -72,7 +71,7 @@ struct bcm203x_data {
|
|||
|
||||
unsigned long state;
|
||||
|
||||
struct timer_list timer;
|
||||
struct work_struct work;
|
||||
|
||||
struct urb *urb;
|
||||
unsigned char *buffer;
|
||||
|
|
@ -105,7 +104,7 @@ static void bcm203x_complete(struct urb *urb)
|
|||
|
||||
data->state = BCM203X_SELECT_MEMORY;
|
||||
|
||||
mod_timer(&data->timer, jiffies + (HZ / 10));
|
||||
schedule_work(&data->work);
|
||||
break;
|
||||
|
||||
case BCM203X_SELECT_MEMORY:
|
||||
|
|
@ -158,9 +157,9 @@ static void bcm203x_complete(struct urb *urb)
|
|||
}
|
||||
}
|
||||
|
||||
static void bcm203x_timer(unsigned long user_data)
|
||||
static void bcm203x_work(void *user_data)
|
||||
{
|
||||
struct bcm203x_data *data = (struct bcm203x_data *) user_data;
|
||||
struct bcm203x_data *data = user_data;
|
||||
|
||||
if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
|
||||
BT_ERR("Can't submit URB");
|
||||
|
|
@ -247,13 +246,11 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
|
|||
|
||||
release_firmware(firmware);
|
||||
|
||||
init_timer(&data->timer);
|
||||
data->timer.function = bcm203x_timer;
|
||||
data->timer.data = (unsigned long) data;
|
||||
INIT_WORK(&data->work, bcm203x_work, (void *) data);
|
||||
|
||||
usb_set_intfdata(intf, data);
|
||||
|
||||
mod_timer(&data->timer, jiffies + HZ);
|
||||
schedule_work(&data->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
|
|||
clear_bit(ready_bit, &(info->tx_state));
|
||||
|
||||
if (bt_cb(skb)->pkt_type & 0x80) {
|
||||
DECLARE_WAIT_QUEUE_HEAD(wq);
|
||||
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
unsigned char baud_reg;
|
||||
|
|
|
|||
|
|
@ -711,6 +711,7 @@ static void dtl1_release(struct pcmcia_device *link)
|
|||
|
||||
static struct pcmcia_device_id dtl1_ids[] = {
|
||||
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
|
||||
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
|
||||
PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
|
||||
PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
|
||||
PCMCIA_DEVICE_NULL
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ static struct usb_device_id blacklist_ids[] = {
|
|||
/* IBM/Lenovo ThinkPad with Broadcom chip */
|
||||
{ USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
|
||||
|
||||
/* ANYCOM Bluetooth USB-200 and USB-250 */
|
||||
{ USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
|
||||
|
||||
/* Microsoft Wireless Transceiver for Bluetooth 2.0 */
|
||||
{ USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
|
||||
|
||||
|
|
|
|||
|
|
@ -409,14 +409,6 @@ config SGI_MBCS
|
|||
If you have an SGI Altix with an attached SABrick
|
||||
say Y or M here, otherwise say N.
|
||||
|
||||
config MSPEC
|
||||
tristate "Memory special operations driver"
|
||||
depends on IA64
|
||||
help
|
||||
If you have an ia64 and you want to enable memory special
|
||||
operations support (formerly known as fetchop), say Y here,
|
||||
otherwise say N.
|
||||
|
||||
source "drivers/serial/Kconfig"
|
||||
|
||||
config UNIX98_PTYS
|
||||
|
|
@ -1046,7 +1038,7 @@ source "drivers/char/tpm/Kconfig"
|
|||
|
||||
config TELCLOCK
|
||||
tristate "Telecom clock driver for MPBL0010 ATCA SBC"
|
||||
depends on EXPERIMENTAL
|
||||
depends on EXPERIMENTAL && X86
|
||||
default n
|
||||
help
|
||||
The telecom clock device is specific to the MPBL0010 ATCA computer and
|
||||
|
|
|
|||
|
|
@ -27,32 +27,42 @@
|
|||
static int uninorth_rev;
|
||||
static int is_u3;
|
||||
|
||||
static char __devinitdata *aperture = NULL;
|
||||
|
||||
static int uninorth_fetch_size(void)
|
||||
{
|
||||
int i;
|
||||
u32 temp;
|
||||
struct aper_size_info_32 *values;
|
||||
int i, size = 0;
|
||||
struct aper_size_info_32 *values =
|
||||
A_SIZE_32(agp_bridge->driver->aperture_sizes);
|
||||
|
||||
pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
|
||||
temp &= ~(0xfffff000);
|
||||
values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
|
||||
if (aperture) {
|
||||
char *save = aperture;
|
||||
|
||||
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
|
||||
if (temp == values[i].size_value) {
|
||||
agp_bridge->previous_size =
|
||||
agp_bridge->current_size = (void *) (values + i);
|
||||
agp_bridge->aperture_size_idx = i;
|
||||
return values[i].size;
|
||||
size = memparse(aperture, &aperture) >> 20;
|
||||
aperture = save;
|
||||
|
||||
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
|
||||
if (size == values[i].size)
|
||||
break;
|
||||
|
||||
if (i == agp_bridge->driver->num_aperture_sizes) {
|
||||
printk(KERN_ERR PFX "Invalid aperture size, using"
|
||||
" default\n");
|
||||
size = 0;
|
||||
aperture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
agp_bridge->previous_size =
|
||||
agp_bridge->current_size = (void *) (values + 1);
|
||||
agp_bridge->aperture_size_idx = 1;
|
||||
return values[1].size;
|
||||
if (!size) {
|
||||
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
|
||||
if (values[i].size == 32)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
agp_bridge->previous_size =
|
||||
agp_bridge->current_size = (void *)(values + i);
|
||||
agp_bridge->aperture_size_idx = i;
|
||||
return values[i].size;
|
||||
}
|
||||
|
||||
static void uninorth_tlbflush(struct agp_memory *mem)
|
||||
|
|
@ -683,5 +693,11 @@ static void __exit agp_uninorth_cleanup(void)
|
|||
module_init(agp_uninorth_init);
|
||||
module_exit(agp_uninorth_cleanup);
|
||||
|
||||
module_param(aperture, charp, 0);
|
||||
MODULE_PARM_DESC(aperture,
|
||||
"Aperture size, must be power of two between 4MB and an\n"
|
||||
"\t\tupper limit specific to the UniNorth revision.\n"
|
||||
"\t\tDefault: 32M");
|
||||
|
||||
MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -237,6 +237,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
|||
|
||||
list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
|
||||
if (!list) {
|
||||
if (map->type == _DRM_REGISTERS)
|
||||
drm_ioremapfree(map->handle, map->size, dev);
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -252,6 +254,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
|||
map->offset;
|
||||
ret = drm_map_handle(dev, &list->hash, user_token, 0);
|
||||
if (ret) {
|
||||
if (map->type == _DRM_REGISTERS)
|
||||
drm_ioremapfree(map->handle, map->size, dev);
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
|
|
|||
|
|
@ -42,13 +42,24 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
|
|||
struct class *drm_sysfs_create(struct module *owner, char *name)
|
||||
{
|
||||
struct class *class;
|
||||
int err;
|
||||
|
||||
class = class_create(owner, name);
|
||||
if (!class)
|
||||
return class;
|
||||
if (!class) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
err = class_create_file(class, &class_attr_version);
|
||||
if (err)
|
||||
goto err_out_class;
|
||||
|
||||
class_create_file(class, &class_attr_version);
|
||||
return class;
|
||||
|
||||
err_out_class:
|
||||
class_destroy(class);
|
||||
err_out:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -96,20 +107,36 @@ static struct class_device_attribute class_device_attrs[] = {
|
|||
struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
|
||||
{
|
||||
struct class_device *class_dev;
|
||||
int i;
|
||||
int i, j, err;
|
||||
|
||||
class_dev = class_device_create(cs, NULL,
|
||||
MKDEV(DRM_MAJOR, head->minor),
|
||||
&(head->dev->pdev)->dev,
|
||||
"card%d", head->minor);
|
||||
if (!class_dev)
|
||||
return NULL;
|
||||
if (!class_dev) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
class_set_devdata(class_dev, head);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
|
||||
class_device_create_file(class_dev, &class_device_attrs[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
|
||||
err = class_device_create_file(class_dev,
|
||||
&class_device_attrs[i]);
|
||||
if (err)
|
||||
goto err_out_files;
|
||||
}
|
||||
|
||||
return class_dev;
|
||||
|
||||
err_out_files:
|
||||
if (i > 0)
|
||||
for (j = 0; j < i; j++)
|
||||
class_device_remove_file(class_dev,
|
||||
&class_device_attrs[i]);
|
||||
class_device_unregister(class_dev);
|
||||
err_out:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ static struct drm_driver driver = {
|
|||
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
|
||||
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
|
||||
DRIVER_IRQ_VBL,
|
||||
.dev_priv_size = sizeof(drm_mga_buf_priv_t),
|
||||
.load = mga_driver_load,
|
||||
.unload = mga_driver_unload,
|
||||
.lastclose = mga_driver_lastclose,
|
||||
|
|
|
|||
|
|
@ -538,6 +538,36 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
|
||||
drm_radeon_kcmd_buffer_t *cmdbuf)
|
||||
{
|
||||
u32 *cmd = (u32 *) cmdbuf->buf;
|
||||
int count, ret;
|
||||
RING_LOCALS;
|
||||
|
||||
count=(cmd[0]>>16) & 0x3fff;
|
||||
|
||||
if ((cmd[1] & 0x8000ffff) != 0x80000810) {
|
||||
DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
ret = r300_check_offset(dev_priv, cmd[2]);
|
||||
if (ret) {
|
||||
DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
BEGIN_RING(count+2);
|
||||
OUT_RING(cmd[0]);
|
||||
OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += (count+2)*4;
|
||||
cmdbuf->bufsz -= (count+2)*4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
|
||||
drm_radeon_kcmd_buffer_t *cmdbuf)
|
||||
{
|
||||
|
|
@ -578,10 +608,11 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
|
|||
case RADEON_CNTL_BITBLT_MULTI:
|
||||
return r300_emit_bitblt_multi(dev_priv, cmdbuf);
|
||||
|
||||
case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
|
||||
return r300_emit_indx_buffer(dev_priv, cmdbuf);
|
||||
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
|
||||
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
|
||||
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
|
||||
case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
|
||||
case RADEON_WAIT_FOR_IDLE:
|
||||
case RADEON_CP_NOP:
|
||||
/* these packets are safe */
|
||||
|
|
|
|||
|
|
@ -275,6 +275,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
|||
unsigned int *cmdsz)
|
||||
{
|
||||
u32 *cmd = (u32 *) cmdbuf->buf;
|
||||
u32 offset, narrays;
|
||||
int count, i, k;
|
||||
|
||||
*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
|
||||
|
||||
|
|
@ -288,10 +290,106 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
|||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
/* Check client state and fix it up if necessary */
|
||||
if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */
|
||||
u32 offset;
|
||||
switch(cmd[0] & 0xff00) {
|
||||
/* XXX Are there old drivers needing other packets? */
|
||||
|
||||
case RADEON_3D_DRAW_IMMD:
|
||||
case RADEON_3D_DRAW_VBUF:
|
||||
case RADEON_3D_DRAW_INDX:
|
||||
case RADEON_WAIT_FOR_IDLE:
|
||||
case RADEON_CP_NOP:
|
||||
case RADEON_3D_CLEAR_ZMASK:
|
||||
/* case RADEON_CP_NEXT_CHAR:
|
||||
case RADEON_CP_PLY_NEXTSCAN:
|
||||
case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
|
||||
/* these packets are safe */
|
||||
break;
|
||||
|
||||
case RADEON_CP_3D_DRAW_IMMD_2:
|
||||
case RADEON_CP_3D_DRAW_VBUF_2:
|
||||
case RADEON_CP_3D_DRAW_INDX_2:
|
||||
case RADEON_3D_CLEAR_HIZ:
|
||||
/* safe but r200 only */
|
||||
if (dev_priv->microcode_version != UCODE_R200) {
|
||||
DRM_ERROR("Invalid 3d packet for r100-class chip\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_3D_LOAD_VBPNTR:
|
||||
count = (cmd[0] >> 16) & 0x3fff;
|
||||
|
||||
if (count > 18) { /* 12 arrays max */
|
||||
DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
|
||||
count);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
/* carefully check packet contents */
|
||||
narrays = cmd[1] & ~0xc000;
|
||||
k = 0;
|
||||
i = 2;
|
||||
while ((k < narrays) && (i < (count + 2))) {
|
||||
i++; /* skip attribute field */
|
||||
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
|
||||
DRM_ERROR
|
||||
("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
|
||||
k, i);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
k++;
|
||||
i++;
|
||||
if (k == narrays)
|
||||
break;
|
||||
/* have one more to process, they come in pairs */
|
||||
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
|
||||
DRM_ERROR
|
||||
("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
|
||||
k, i);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
k++;
|
||||
i++;
|
||||
}
|
||||
/* do the counts match what we expect ? */
|
||||
if ((k != narrays) || (i != (count + 2))) {
|
||||
DRM_ERROR
|
||||
("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
|
||||
k, i, narrays, count + 1);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_3D_RNDR_GEN_INDX_PRIM:
|
||||
if (dev_priv->microcode_version != UCODE_R100) {
|
||||
DRM_ERROR("Invalid 3d packet for r200-class chip\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) {
|
||||
DRM_ERROR("Invalid rndr_gen_indx offset\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CP_INDX_BUFFER:
|
||||
if (dev_priv->microcode_version != UCODE_R200) {
|
||||
DRM_ERROR("Invalid 3d packet for r100-class chip\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if ((cmd[1] & 0x8000ffff) != 0x80000810) {
|
||||
DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) {
|
||||
DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CNTL_HOSTDATA_BLT:
|
||||
case RADEON_CNTL_PAINT_MULTI:
|
||||
case RADEON_CNTL_BITBLT_MULTI:
|
||||
/* MSB of opcode: next DWORD GUI_CNTL */
|
||||
if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
||||
| RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
|
||||
offset = cmd[2] << 10;
|
||||
|
|
@ -313,6 +411,11 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
|||
}
|
||||
cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -728,6 +728,7 @@ static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init)
|
|||
dev_priv->status = NULL;
|
||||
}
|
||||
if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) {
|
||||
dev->agp_buffer_token = init->buffers_offset;
|
||||
dev->agp_buffer_map = drm_core_findmap(dev,
|
||||
init->buffers_offset);
|
||||
if (!dev->agp_buffer_map) {
|
||||
|
|
|
|||
|
|
@ -994,7 +994,7 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
|
|||
if (cmdbuf.size) {
|
||||
kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER);
|
||||
if (kcmd_addr == NULL)
|
||||
return ENOMEM;
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr,
|
||||
cmdbuf.size * 8))
|
||||
|
|
|
|||
|
|
@ -1157,6 +1157,7 @@ static int __init pc_init(void)
|
|||
int crd;
|
||||
struct board_info *bd;
|
||||
unsigned char board_id = 0;
|
||||
int err = -ENOMEM;
|
||||
|
||||
int pci_boards_found, pci_count;
|
||||
|
||||
|
|
@ -1164,13 +1165,11 @@ static int __init pc_init(void)
|
|||
|
||||
pc_driver = alloc_tty_driver(MAX_ALLOC);
|
||||
if (!pc_driver)
|
||||
return -ENOMEM;
|
||||
goto out1;
|
||||
|
||||
pc_info = alloc_tty_driver(MAX_ALLOC);
|
||||
if (!pc_info) {
|
||||
put_tty_driver(pc_driver);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!pc_info)
|
||||
goto out2;
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
If epca_setup has not been ran by LILO set num_cards to defaults; copy
|
||||
|
|
@ -1370,11 +1369,17 @@ static int __init pc_init(void)
|
|||
|
||||
} /* End for each card */
|
||||
|
||||
if (tty_register_driver(pc_driver))
|
||||
panic("Couldn't register Digi PC/ driver");
|
||||
err = tty_register_driver(pc_driver);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Couldn't register Digi PC/ driver");
|
||||
goto out3;
|
||||
}
|
||||
|
||||
if (tty_register_driver(pc_info))
|
||||
panic("Couldn't register Digi PC/ info ");
|
||||
err = tty_register_driver(pc_info);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Couldn't register Digi PC/ info ");
|
||||
goto out4;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
Start up the poller to check for events on all enabled boards
|
||||
|
|
@ -1385,6 +1390,15 @@ static int __init pc_init(void)
|
|||
mod_timer(&epca_timer, jiffies + HZ/25);
|
||||
return 0;
|
||||
|
||||
out4:
|
||||
tty_unregister_driver(pc_driver);
|
||||
out3:
|
||||
put_tty_driver(pc_info);
|
||||
out2:
|
||||
put_tty_driver(pc_driver);
|
||||
out1:
|
||||
return err;
|
||||
|
||||
} /* End pc_init */
|
||||
|
||||
/* ------------------ Begin post_fep_init ---------------------- */
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ int zft_vmalloc_once(void *new, size_t size)
|
|||
peak_memory = used_memory;
|
||||
}
|
||||
TRACE_ABORT(0, ft_t_noise,
|
||||
"allocated buffer @ %p, %d bytes", *(void **)new, size);
|
||||
"allocated buffer @ %p, %zd bytes", *(void **)new, size);
|
||||
}
|
||||
int zft_vmalloc_always(void *new, size_t size)
|
||||
{
|
||||
|
|
@ -101,7 +101,7 @@ void zft_vfree(void *old, size_t size)
|
|||
if (*(void **)old) {
|
||||
vfree(*(void **)old);
|
||||
used_memory -= size;
|
||||
TRACE(ft_t_noise, "released buffer @ %p, %d bytes",
|
||||
TRACE(ft_t_noise, "released buffer @ %p, %zd bytes",
|
||||
*(void **)old, size);
|
||||
*(void **)old = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1007,7 +1007,7 @@ i2InputAvailable(i2ChanStrPtr pCh)
|
|||
// applications that one cannot break out of.
|
||||
//******************************************************************************
|
||||
static int
|
||||
i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
|
||||
i2Output(i2ChanStrPtr pCh, const char *pSource, int count)
|
||||
{
|
||||
i2eBordStrPtr pB;
|
||||
unsigned char *pInsert;
|
||||
|
|
@ -1020,7 +1020,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
|
|||
|
||||
int bailout = 10;
|
||||
|
||||
ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user );
|
||||
ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 );
|
||||
|
||||
// Ensure channel structure seems real
|
||||
if ( !i2Validate ( pCh ) )
|
||||
|
|
@ -1087,12 +1087,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
|
|||
DATA_COUNT_OF(pInsert) = amountToMove;
|
||||
|
||||
// Move the data
|
||||
if ( user ) {
|
||||
rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource,
|
||||
amountToMove );
|
||||
} else {
|
||||
memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
|
||||
}
|
||||
memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
|
||||
// Adjust pointers and indices
|
||||
pSource += amountToMove;
|
||||
pCh->Obuf_char_count += amountToMove;
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ static int i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...);
|
|||
static int i2GetStatus(i2ChanStrPtr, int);
|
||||
static int i2Input(i2ChanStrPtr);
|
||||
static int i2InputFlush(i2ChanStrPtr);
|
||||
static int i2Output(i2ChanStrPtr, const char *, int, int);
|
||||
static int i2Output(i2ChanStrPtr, const char *, int);
|
||||
static int i2OutputFree(i2ChanStrPtr);
|
||||
static int i2ServiceBoard(i2eBordStrPtr);
|
||||
static void i2DrainOutput(i2ChanStrPtr, int);
|
||||
|
|
|
|||
|
|
@ -1704,7 +1704,7 @@ ip2_write( PTTY tty, const unsigned char *pData, int count)
|
|||
|
||||
/* This is the actual move bit. Make sure it does what we need!!!!! */
|
||||
WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
|
||||
bytesSent = i2Output( pCh, pData, count, 0 );
|
||||
bytesSent = i2Output( pCh, pData, count);
|
||||
WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
|
||||
|
||||
ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
|
||||
|
|
@ -1764,7 +1764,7 @@ ip2_flush_chars( PTTY tty )
|
|||
//
|
||||
// We may need to restart i2Output if it does not fullfill this request
|
||||
//
|
||||
strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
|
||||
strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff);
|
||||
if ( strip != pCh->Pbuf_stuff ) {
|
||||
memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -376,13 +376,23 @@ static void free_recv_msg_list(struct list_head *q)
|
|||
}
|
||||
}
|
||||
|
||||
static void free_smi_msg_list(struct list_head *q)
|
||||
{
|
||||
struct ipmi_smi_msg *msg, *msg2;
|
||||
|
||||
list_for_each_entry_safe(msg, msg2, q, link) {
|
||||
list_del(&msg->link);
|
||||
ipmi_free_smi_msg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void clean_up_interface_data(ipmi_smi_t intf)
|
||||
{
|
||||
int i;
|
||||
struct cmd_rcvr *rcvr, *rcvr2;
|
||||
struct list_head list;
|
||||
|
||||
free_recv_msg_list(&intf->waiting_msgs);
|
||||
free_smi_msg_list(&intf->waiting_msgs);
|
||||
free_recv_msg_list(&intf->waiting_events);
|
||||
|
||||
/* Wholesale remove all the entries from the list in the
|
||||
|
|
@ -1844,7 +1854,7 @@ static ssize_t provides_dev_sdrs_show(struct device *dev,
|
|||
struct bmc_device *bmc = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, 10, "%u\n",
|
||||
bmc->id.device_revision && 0x80 >> 7);
|
||||
(bmc->id.device_revision & 0x80) >> 7);
|
||||
}
|
||||
|
||||
static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
|
||||
|
|
@ -1853,7 +1863,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
|
|||
struct bmc_device *bmc = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, 20, "%u\n",
|
||||
bmc->id.device_revision && 0x0F);
|
||||
bmc->id.device_revision & 0x0F);
|
||||
}
|
||||
|
||||
static ssize_t firmware_rev_show(struct device *dev,
|
||||
|
|
@ -1928,13 +1938,8 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
|
|||
(long long) bmc->guid[8]);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_bmc_device(struct kref *ref)
|
||||
static void remove_files(struct bmc_device *bmc)
|
||||
{
|
||||
struct bmc_device *bmc;
|
||||
|
||||
bmc = container_of(ref, struct bmc_device, refcount);
|
||||
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->device_id_attr);
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
|
|
@ -1951,12 +1956,23 @@ cleanup_bmc_device(struct kref *ref)
|
|||
&bmc->manufacturer_id_attr);
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->product_id_attr);
|
||||
|
||||
if (bmc->id.aux_firmware_revision_set)
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->aux_firmware_rev_attr);
|
||||
if (bmc->guid_set)
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->guid_attr);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_bmc_device(struct kref *ref)
|
||||
{
|
||||
struct bmc_device *bmc;
|
||||
|
||||
bmc = container_of(ref, struct bmc_device, refcount);
|
||||
|
||||
remove_files(bmc);
|
||||
platform_device_unregister(bmc->dev);
|
||||
kfree(bmc);
|
||||
}
|
||||
|
|
@ -1977,6 +1993,79 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
|
|||
mutex_unlock(&ipmidriver_mutex);
|
||||
}
|
||||
|
||||
static int create_files(struct bmc_device *bmc)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->device_id_attr);
|
||||
if (err) goto out;
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->provides_dev_sdrs_attr);
|
||||
if (err) goto out_devid;
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->revision_attr);
|
||||
if (err) goto out_sdrs;
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->firmware_rev_attr);
|
||||
if (err) goto out_rev;
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->version_attr);
|
||||
if (err) goto out_firm;
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->add_dev_support_attr);
|
||||
if (err) goto out_version;
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->manufacturer_id_attr);
|
||||
if (err) goto out_add_dev;
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->product_id_attr);
|
||||
if (err) goto out_manu;
|
||||
if (bmc->id.aux_firmware_revision_set) {
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->aux_firmware_rev_attr);
|
||||
if (err) goto out_prod_id;
|
||||
}
|
||||
if (bmc->guid_set) {
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->guid_attr);
|
||||
if (err) goto out_aux_firm;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_aux_firm:
|
||||
if (bmc->id.aux_firmware_revision_set)
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->aux_firmware_rev_attr);
|
||||
out_prod_id:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->product_id_attr);
|
||||
out_manu:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->manufacturer_id_attr);
|
||||
out_add_dev:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->add_dev_support_attr);
|
||||
out_version:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->version_attr);
|
||||
out_firm:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->firmware_rev_attr);
|
||||
out_rev:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->revision_attr);
|
||||
out_sdrs:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->provides_dev_sdrs_attr);
|
||||
out_devid:
|
||||
device_remove_file(&bmc->dev->dev,
|
||||
&bmc->device_id_attr);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ipmi_bmc_register(ipmi_smi_t intf)
|
||||
{
|
||||
int rv;
|
||||
|
|
@ -2029,7 +2118,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
|
|||
dev_set_drvdata(&bmc->dev->dev, bmc);
|
||||
kref_init(&bmc->refcount);
|
||||
|
||||
rv = platform_device_register(bmc->dev);
|
||||
rv = platform_device_add(bmc->dev);
|
||||
mutex_unlock(&ipmidriver_mutex);
|
||||
if (rv) {
|
||||
printk(KERN_ERR
|
||||
|
|
@ -2051,7 +2140,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
|
|||
bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
|
||||
bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
|
||||
|
||||
|
||||
bmc->revision_attr.attr.name = "revision";
|
||||
bmc->revision_attr.attr.owner = THIS_MODULE;
|
||||
bmc->revision_attr.attr.mode = S_IRUGO;
|
||||
|
|
@ -2093,28 +2181,14 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
|
|||
bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
|
||||
bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
|
||||
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->device_id_attr);
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->provides_dev_sdrs_attr);
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->revision_attr);
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->firmware_rev_attr);
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->version_attr);
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->add_dev_support_attr);
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->manufacturer_id_attr);
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->product_id_attr);
|
||||
if (bmc->id.aux_firmware_revision_set)
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->aux_firmware_rev_attr);
|
||||
if (bmc->guid_set)
|
||||
device_create_file(&bmc->dev->dev,
|
||||
&bmc->guid_attr);
|
||||
rv = create_files(bmc);
|
||||
if (rv) {
|
||||
mutex_lock(&ipmidriver_mutex);
|
||||
platform_device_unregister(bmc->dev);
|
||||
mutex_unlock(&ipmidriver_mutex);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
printk(KERN_INFO
|
||||
"ipmi: Found new BMC (man_id: 0x%6.6x, "
|
||||
|
|
@ -3168,7 +3242,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
|
|||
report the error immediately. */
|
||||
if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0)
|
||||
&& (msg->rsp[2] != IPMI_NODE_BUSY_ERR)
|
||||
&& (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR))
|
||||
&& (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)
|
||||
&& (msg->rsp[2] != IPMI_BUS_ERR)
|
||||
&& (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR))
|
||||
{
|
||||
int chan = msg->rsp[3] & 0xf;
|
||||
|
||||
|
|
|
|||
|
|
@ -1211,7 +1211,7 @@ static void intf_mem_outb(struct si_sm_io *io, unsigned int offset,
|
|||
static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset)
|
||||
{
|
||||
return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift)
|
||||
&& 0xff;
|
||||
& 0xff;
|
||||
}
|
||||
|
||||
static void intf_mem_outw(struct si_sm_io *io, unsigned int offset,
|
||||
|
|
@ -1223,7 +1223,7 @@ static void intf_mem_outw(struct si_sm_io *io, unsigned int offset,
|
|||
static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset)
|
||||
{
|
||||
return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift)
|
||||
&& 0xff;
|
||||
& 0xff;
|
||||
}
|
||||
|
||||
static void intf_mem_outl(struct si_sm_io *io, unsigned int offset,
|
||||
|
|
@ -1236,7 +1236,7 @@ static void intf_mem_outl(struct si_sm_io *io, unsigned int offset,
|
|||
static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset)
|
||||
{
|
||||
return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift)
|
||||
&& 0xff;
|
||||
& 0xff;
|
||||
}
|
||||
|
||||
static void mem_outq(struct si_sm_io *io, unsigned int offset,
|
||||
|
|
@ -1789,7 +1789,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
|
|||
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return ENOMEM;
|
||||
return -ENOMEM;
|
||||
|
||||
info->addr_source = "PCI";
|
||||
|
||||
|
|
@ -1810,7 +1810,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
|
|||
kfree(info);
|
||||
printk(KERN_INFO "ipmi_si: %s: Unknown IPMI type: %d\n",
|
||||
pci_name(pdev), class_type);
|
||||
return ENOMEM;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rv = pci_enable_device(pdev);
|
||||
|
|
@ -1867,7 +1867,7 @@ static int ipmi_pci_resume(struct pci_dev *pdev)
|
|||
|
||||
static struct pci_device_id ipmi_pci_devices[] = {
|
||||
{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
|
||||
{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) }
|
||||
{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
|
||||
|
||||
|
|
@ -2346,7 +2346,7 @@ static int try_smi_init(struct smi_info *new_smi)
|
|||
new_smi->dev = &new_smi->pdev->dev;
|
||||
new_smi->dev->driver = &ipmi_driver;
|
||||
|
||||
rv = platform_device_register(new_smi->pdev);
|
||||
rv = platform_device_add(new_smi->pdev);
|
||||
if (rv) {
|
||||
printk(KERN_ERR
|
||||
"ipmi_si_intf:"
|
||||
|
|
|
|||
|
|
@ -1062,11 +1062,12 @@ static void isicom_shutdown_port(struct isi_port *port)
|
|||
static void isicom_close(struct tty_struct *tty, struct file *filp)
|
||||
{
|
||||
struct isi_port *port = tty->driver_data;
|
||||
struct isi_board *card = port->card;
|
||||
struct isi_board *card;
|
||||
unsigned long flags;
|
||||
|
||||
if (!port)
|
||||
return;
|
||||
card = port->card;
|
||||
if (isicom_paranoia_check(port, tty->name, "isicom_close"))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/backing-dev.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/pipe_fs_i.h>
|
||||
#include <linux/pfn.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
|
|
@ -292,8 +293,8 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
|
|||
{
|
||||
unsigned long pfn;
|
||||
|
||||
/* Turn a kernel-virtual address into a physical page frame */
|
||||
pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
|
||||
/* Turn a pfn offset into an absolute pfn */
|
||||
pfn = PFN_DOWN(virt_to_phys((void *)PAGE_OFFSET)) + vma->vm_pgoff;
|
||||
|
||||
/*
|
||||
* RED-PEN: on some architectures there is more mapped memory
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ static moxa_isa_board_conf moxa_isa_boards[] =
|
|||
typedef struct _moxa_pci_devinfo {
|
||||
ushort busNum;
|
||||
ushort devNum;
|
||||
struct pci_dev *pdev;
|
||||
} moxa_pci_devinfo;
|
||||
|
||||
typedef struct _moxa_board_conf {
|
||||
|
|
@ -324,6 +325,9 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf
|
|||
board->busType = MOXA_BUS_TYPE_PCI;
|
||||
board->pciInfo.busNum = p->bus->number;
|
||||
board->pciInfo.devNum = p->devfn >> 3;
|
||||
board->pciInfo.pdev = p;
|
||||
/* don't lose the reference in the next pci_get_device iteration */
|
||||
pci_dev_get(p);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -493,6 +497,11 @@ static void __exit moxa_exit(void)
|
|||
if (tty_unregister_driver(moxaDriver))
|
||||
printk("Couldn't unregister MOXA Intellio family serial driver\n");
|
||||
put_tty_driver(moxaDriver);
|
||||
|
||||
for (i = 0; i < MAX_BOARDS; i++)
|
||||
if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
|
||||
pci_dev_put(moxa_boards[i].pciInfo.pdev);
|
||||
|
||||
if (verbose)
|
||||
printk("Done\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,11 @@ enum {
|
|||
MSPEC_UNCACHED
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SGI_SN
|
||||
static int is_sn2;
|
||||
#else
|
||||
#define is_sn2 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* One of these structures is allocated when an mspec region is mmaped. The
|
||||
|
|
@ -211,7 +215,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
|
|||
if (vdata->type == MSPEC_FETCHOP)
|
||||
paddr = TO_AMO(maddr);
|
||||
else
|
||||
paddr = __pa(TO_CAC(maddr));
|
||||
paddr = maddr & ~__IA64_UNCACHED_OFFSET;
|
||||
|
||||
pfn = paddr >> PAGE_SHIFT;
|
||||
|
||||
|
|
@ -335,6 +339,7 @@ mspec_init(void)
|
|||
* The fetchop device only works on SN2 hardware, uncached and cached
|
||||
* memory drivers should both be valid on all ia64 hardware
|
||||
*/
|
||||
#ifdef CONFIG_SGI_SN
|
||||
if (ia64_platform_is("sn2")) {
|
||||
is_sn2 = 1;
|
||||
if (is_shub2()) {
|
||||
|
|
@ -363,6 +368,7 @@ mspec_init(void)
|
|||
goto free_scratch_pages;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ret = misc_register(&cached_miscdev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: failed to register device %i\n",
|
||||
|
|
|
|||
|
|
@ -645,6 +645,7 @@ void add_input_randomness(unsigned int type, unsigned int code,
|
|||
add_timer_randomness(&input_timer_state,
|
||||
(type << 4) ^ code ^ (code >> 4) ^ value);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(add_input_randomness);
|
||||
|
||||
void add_interrupt_randomness(int irq)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
** the host.
|
||||
*/
|
||||
struct Host {
|
||||
struct pci_dev *pdev;
|
||||
unsigned char Type; /* RIO_EISA, RIO_MCA, ... */
|
||||
unsigned char Ivec; /* POLLED or ivec number */
|
||||
unsigned char Mode; /* Control stuff */
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,10 @@ static int __init rio_init(void)
|
|||
rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
|
||||
|
||||
fix_rio_pci(pdev);
|
||||
|
||||
p->RIOHosts[p->RIONumHosts].pdev = pdev;
|
||||
pci_dev_get(pdev);
|
||||
|
||||
p->RIOLastPCISearch = 0;
|
||||
p->RIONumHosts++;
|
||||
found++;
|
||||
|
|
@ -1066,6 +1070,9 @@ static int __init rio_init(void)
|
|||
((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24);
|
||||
rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
|
||||
|
||||
p->RIOHosts[p->RIONumHosts].pdev = pdev;
|
||||
pci_dev_get(pdev);
|
||||
|
||||
p->RIOLastPCISearch = 0;
|
||||
p->RIONumHosts++;
|
||||
found++;
|
||||
|
|
@ -1181,6 +1188,8 @@ static void __exit rio_exit(void)
|
|||
}
|
||||
/* It is safe/allowed to del_timer a non-active timer */
|
||||
del_timer(&hp->timer);
|
||||
if (hp->Type == RIO_PCI)
|
||||
pci_dev_put(hp->pdev);
|
||||
}
|
||||
|
||||
if (misc_deregister(&rio_fw_device) < 0) {
|
||||
|
|
|
|||
|
|
@ -662,7 +662,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
|
|||
p->RIOError.Error = COPYIN_FAILED;
|
||||
return -EFAULT;
|
||||
}
|
||||
if (portStats.port >= RIO_PORTS) {
|
||||
if (portStats.port < 0 || portStats.port >= RIO_PORTS) {
|
||||
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
|
@ -702,7 +702,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
|
|||
p->RIOError.Error = COPYIN_FAILED;
|
||||
return -EFAULT;
|
||||
}
|
||||
if (portStats.port >= RIO_PORTS) {
|
||||
if (portStats.port < 0 || portStats.port >= RIO_PORTS) {
|
||||
p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -839,7 +839,7 @@ shutdown(struct cyclades_port * info)
|
|||
local_irq_save(flags);
|
||||
if (info->xmit_buf){
|
||||
free_page((unsigned long) info->xmit_buf);
|
||||
info->xmit_buf = 0;
|
||||
info->xmit_buf = NULL;
|
||||
}
|
||||
|
||||
base_addr[CyCAR] = (u_char)channel;
|
||||
|
|
@ -1354,7 +1354,7 @@ cy_unthrottle(struct tty_struct * tty)
|
|||
|
||||
static int
|
||||
get_serial_info(struct cyclades_port * info,
|
||||
struct serial_struct * retinfo)
|
||||
struct serial_struct __user * retinfo)
|
||||
{
|
||||
struct serial_struct tmp;
|
||||
|
||||
|
|
@ -1376,7 +1376,7 @@ get_serial_info(struct cyclades_port * info,
|
|||
|
||||
static int
|
||||
set_serial_info(struct cyclades_port * info,
|
||||
struct serial_struct * new_info)
|
||||
struct serial_struct __user * new_info)
|
||||
{
|
||||
struct serial_struct new_serial;
|
||||
struct cyclades_port old_info;
|
||||
|
|
@ -1503,7 +1503,7 @@ send_break( struct cyclades_port * info, int duration)
|
|||
} /* send_break */
|
||||
|
||||
static int
|
||||
get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
|
||||
get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon)
|
||||
{
|
||||
|
||||
if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
|
||||
|
|
@ -1516,7 +1516,7 @@ get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
|
|||
}
|
||||
|
||||
static int
|
||||
set_threshold(struct cyclades_port * info, unsigned long *arg)
|
||||
set_threshold(struct cyclades_port * info, unsigned long __user *arg)
|
||||
{
|
||||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||||
unsigned long value;
|
||||
|
|
@ -1533,7 +1533,7 @@ set_threshold(struct cyclades_port * info, unsigned long *arg)
|
|||
}
|
||||
|
||||
static int
|
||||
get_threshold(struct cyclades_port * info, unsigned long *value)
|
||||
get_threshold(struct cyclades_port * info, unsigned long __user *value)
|
||||
{
|
||||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||||
int channel;
|
||||
|
|
@ -1546,7 +1546,7 @@ get_threshold(struct cyclades_port * info, unsigned long *value)
|
|||
}
|
||||
|
||||
static int
|
||||
set_default_threshold(struct cyclades_port * info, unsigned long *arg)
|
||||
set_default_threshold(struct cyclades_port * info, unsigned long __user *arg)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
|
|
@ -1558,13 +1558,13 @@ set_default_threshold(struct cyclades_port * info, unsigned long *arg)
|
|||
}
|
||||
|
||||
static int
|
||||
get_default_threshold(struct cyclades_port * info, unsigned long *value)
|
||||
get_default_threshold(struct cyclades_port * info, unsigned long __user *value)
|
||||
{
|
||||
return put_user(info->default_threshold,value);
|
||||
}
|
||||
|
||||
static int
|
||||
set_timeout(struct cyclades_port * info, unsigned long *arg)
|
||||
set_timeout(struct cyclades_port * info, unsigned long __user *arg)
|
||||
{
|
||||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||||
int channel;
|
||||
|
|
@ -1581,7 +1581,7 @@ set_timeout(struct cyclades_port * info, unsigned long *arg)
|
|||
}
|
||||
|
||||
static int
|
||||
get_timeout(struct cyclades_port * info, unsigned long *value)
|
||||
get_timeout(struct cyclades_port * info, unsigned long __user *value)
|
||||
{
|
||||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||||
int channel;
|
||||
|
|
@ -1601,7 +1601,7 @@ set_default_timeout(struct cyclades_port * info, unsigned long value)
|
|||
}
|
||||
|
||||
static int
|
||||
get_default_timeout(struct cyclades_port * info, unsigned long *value)
|
||||
get_default_timeout(struct cyclades_port * info, unsigned long __user *value)
|
||||
{
|
||||
return put_user(info->default_timeout,value);
|
||||
}
|
||||
|
|
@ -1613,6 +1613,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
|
|||
unsigned long val;
|
||||
struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
|
||||
int ret_val = 0;
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
||||
#ifdef SERIAL_DEBUG_OTHER
|
||||
printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
|
||||
|
|
@ -1620,28 +1621,28 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
|
|||
|
||||
switch (cmd) {
|
||||
case CYGETMON:
|
||||
ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
|
||||
ret_val = get_mon_info(info, argp);
|
||||
break;
|
||||
case CYGETTHRESH:
|
||||
ret_val = get_threshold(info, (unsigned long *)arg);
|
||||
ret_val = get_threshold(info, argp);
|
||||
break;
|
||||
case CYSETTHRESH:
|
||||
ret_val = set_threshold(info, (unsigned long *)arg);
|
||||
ret_val = set_threshold(info, argp);
|
||||
break;
|
||||
case CYGETDEFTHRESH:
|
||||
ret_val = get_default_threshold(info, (unsigned long *)arg);
|
||||
ret_val = get_default_threshold(info, argp);
|
||||
break;
|
||||
case CYSETDEFTHRESH:
|
||||
ret_val = set_default_threshold(info, (unsigned long *)arg);
|
||||
ret_val = set_default_threshold(info, argp);
|
||||
break;
|
||||
case CYGETTIMEOUT:
|
||||
ret_val = get_timeout(info, (unsigned long *)arg);
|
||||
ret_val = get_timeout(info, argp);
|
||||
break;
|
||||
case CYSETTIMEOUT:
|
||||
ret_val = set_timeout(info, (unsigned long *)arg);
|
||||
ret_val = set_timeout(info, argp);
|
||||
break;
|
||||
case CYGETDEFTIMEOUT:
|
||||
ret_val = get_default_timeout(info, (unsigned long *)arg);
|
||||
ret_val = get_default_timeout(info, argp);
|
||||
break;
|
||||
case CYSETDEFTIMEOUT:
|
||||
ret_val = set_default_timeout(info, (unsigned long)arg);
|
||||
|
|
@ -1664,21 +1665,20 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
|
|||
|
||||
/* The following commands are incompletely implemented!!! */
|
||||
case TIOCGSOFTCAR:
|
||||
ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
|
||||
ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
|
||||
break;
|
||||
case TIOCSSOFTCAR:
|
||||
ret_val = get_user(val, (unsigned long *) arg);
|
||||
ret_val = get_user(val, (unsigned long __user *) argp);
|
||||
if (ret_val)
|
||||
break;
|
||||
tty->termios->c_cflag =
|
||||
((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
|
||||
break;
|
||||
case TIOCGSERIAL:
|
||||
ret_val = get_serial_info(info, (struct serial_struct *) arg);
|
||||
ret_val = get_serial_info(info, argp);
|
||||
break;
|
||||
case TIOCSSERIAL:
|
||||
ret_val = set_serial_info(info,
|
||||
(struct serial_struct *) arg);
|
||||
ret_val = set_serial_info(info, argp);
|
||||
break;
|
||||
default:
|
||||
ret_val = -ENOIOCTLCMD;
|
||||
|
|
@ -1773,7 +1773,7 @@ cy_close(struct tty_struct * tty, struct file * filp)
|
|||
tty->driver->flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
info->event = 0;
|
||||
info->tty = 0;
|
||||
info->tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
if (info->close_delay) {
|
||||
msleep_interruptible(jiffies_to_msecs(info->close_delay));
|
||||
|
|
@ -2250,7 +2250,7 @@ scrn[1] = '\0';
|
|||
info->card = index;
|
||||
info->line = port_num;
|
||||
info->flags = STD_COM_FLAGS;
|
||||
info->tty = 0;
|
||||
info->tty = NULL;
|
||||
info->xmit_fifo_size = 12;
|
||||
info->cor1 = CyPARITY_NONE|Cy_8_BITS;
|
||||
info->cor2 = CyETC;
|
||||
|
|
|
|||
|
|
@ -183,11 +183,6 @@ static int sx_poll = HZ;
|
|||
|
||||
static struct tty_driver *specialix_driver;
|
||||
|
||||
static unsigned long baud_table[] = {
|
||||
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
|
||||
9600, 19200, 38400, 57600, 115200, 0,
|
||||
};
|
||||
|
||||
static struct specialix_board sx_board[SX_NBOARD] = {
|
||||
{ 0, SX_IOBASE1, 9, },
|
||||
{ 0, SX_IOBASE2, 11, },
|
||||
|
|
@ -1090,9 +1085,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
|
|||
|
||||
if (baud == 38400) {
|
||||
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
|
||||
baud ++;
|
||||
baud = 57600;
|
||||
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
|
||||
baud += 2;
|
||||
baud = 115200;
|
||||
}
|
||||
|
||||
if (!baud) {
|
||||
|
|
@ -1150,11 +1145,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
|
|||
sx_out(bp, CD186x_RBPRL, tmp & 0xff);
|
||||
sx_out(bp, CD186x_TBPRL, tmp & 0xff);
|
||||
spin_unlock_irqrestore(&bp->lock, flags);
|
||||
if (port->custom_divisor) {
|
||||
if (port->custom_divisor)
|
||||
baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
|
||||
baud = ( baud + 5 ) / 10;
|
||||
} else
|
||||
baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
|
||||
baud = (baud + 5) / 10; /* Estimated CPS */
|
||||
|
||||
/* Two timer ticks seems enough to wakeup something like SLIP driver */
|
||||
tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
|
||||
|
|
|
|||
|
|
@ -2602,7 +2602,7 @@ static void __exit sx_exit (void)
|
|||
}
|
||||
}
|
||||
if (misc_deregister(&sx_fw_device) < 0) {
|
||||
printk (KERN_INFO "sx: couldn't deregister firmware loader devic\n");
|
||||
printk (KERN_INFO "sx: couldn't deregister firmware loader device\n");
|
||||
}
|
||||
sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", sx_initialized);
|
||||
if (sx_initialized)
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@ static MGSL_PARAMS default_params = {
|
|||
};
|
||||
|
||||
#define SHARED_MEM_ADDRESS_SIZE 0x40000
|
||||
#define BUFFERLISTSIZE (PAGE_SIZE)
|
||||
#define DMABUFFERSIZE (PAGE_SIZE)
|
||||
#define BUFFERLISTSIZE 4096
|
||||
#define DMABUFFERSIZE 4096
|
||||
#define MAXRXFRAMES 7
|
||||
|
||||
typedef struct _DMABUFFERENTRY
|
||||
|
|
|
|||
|
|
@ -1153,7 +1153,14 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
|
|||
|
||||
spin_unlock(&driver_lock);
|
||||
|
||||
sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
|
||||
if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
|
||||
list_del(&chip->list);
|
||||
put_device(dev);
|
||||
clear_bit(chip->dev_num, dev_mask);
|
||||
kfree(chip);
|
||||
kfree(devname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chip->bios_dir = tpm_bios_log_setup(devname);
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,9 @@ static int __init init_atmel(void)
|
|||
unsigned long base;
|
||||
struct tpm_chip *chip;
|
||||
|
||||
driver_register(&atml_drv);
|
||||
rc = driver_register(&atml_drv);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if ((iobase = atmel_get_base_addr(&base, ®ion_size)) == NULL) {
|
||||
rc = -ENODEV;
|
||||
|
|
@ -195,10 +197,8 @@ static int __init init_atmel(void)
|
|||
(atmel_request_region
|
||||
(tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
|
||||
|
||||
|
||||
if (IS_ERR
|
||||
(pdev =
|
||||
platform_device_register_simple("tpm_atmel", -1, NULL, 0))) {
|
||||
pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0);
|
||||
if (IS_ERR(pdev)) {
|
||||
rc = PTR_ERR(pdev);
|
||||
goto err_rel_reg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ static struct device_driver nsc_drv = {
|
|||
static int __init init_nsc(void)
|
||||
{
|
||||
int rc = 0;
|
||||
int lo, hi;
|
||||
int lo, hi, err;
|
||||
int nscAddrBase = TPM_ADDR;
|
||||
struct tpm_chip *chip;
|
||||
unsigned long base;
|
||||
|
|
@ -297,7 +297,9 @@ static int __init init_nsc(void)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
driver_register(&nsc_drv);
|
||||
err = driver_register(&nsc_drv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
|
||||
lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ config WATCHDOG
|
|||
subsequently opening the file and then failing to write to it for
|
||||
longer than 1 minute will result in rebooting the machine. This
|
||||
could be useful for a networked machine that needs to come back
|
||||
online as fast as possible after a lock-up. There's both a watchdog
|
||||
on-line as fast as possible after a lock-up. There's both a watchdog
|
||||
implementation entirely in software (which can sometimes fail to
|
||||
reboot the machine) and a driver for hardware watchdog boards, which
|
||||
are more robust and can also keep track of the temperature inside
|
||||
|
|
@ -60,7 +60,7 @@ config SOFT_WATCHDOG
|
|||
|
||||
# ARM Architecture
|
||||
|
||||
config AT91_WATCHDOG
|
||||
config AT91RM9200_WATCHDOG
|
||||
tristate "AT91RM9200 watchdog"
|
||||
depends on WATCHDOG && ARCH_AT91RM9200
|
||||
help
|
||||
|
|
@ -71,7 +71,7 @@ config 21285_WATCHDOG
|
|||
tristate "DC21285 watchdog"
|
||||
depends on WATCHDOG && FOOTBRIDGE
|
||||
help
|
||||
The Intel Footbridge chip contains a builtin watchdog circuit. Say Y
|
||||
The Intel Footbridge chip contains a built-in watchdog circuit. Say Y
|
||||
here if you wish to use this. Alternatively say M to compile the
|
||||
driver as a module, which will be called wdt285.
|
||||
|
||||
|
|
@ -269,11 +269,11 @@ config IB700_WDT
|
|||
Most people will say N.
|
||||
|
||||
config IBMASR
|
||||
tristate "IBM Automatic Server Restart"
|
||||
depends on WATCHDOG && X86
|
||||
help
|
||||
tristate "IBM Automatic Server Restart"
|
||||
depends on WATCHDOG && X86
|
||||
help
|
||||
This is the driver for the IBM Automatic Server Restart watchdog
|
||||
timer builtin into some eServer xSeries machines.
|
||||
timer built-in into some eServer xSeries machines.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ibmasr.
|
||||
|
|
@ -316,13 +316,16 @@ config I8XX_TCO
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called i8xx_tco.
|
||||
|
||||
Note: This driver will be removed in the near future. Please
|
||||
use the Intel TCO Timer/Watchdog driver.
|
||||
|
||||
config ITCO_WDT
|
||||
tristate "Intel TCO Timer/Watchdog (EXPERIMENTAL)"
|
||||
depends on WATCHDOG && (X86 || IA64) && PCI && EXPERIMENTAL
|
||||
tristate "Intel TCO Timer/Watchdog"
|
||||
depends on WATCHDOG && (X86 || IA64) && PCI
|
||||
---help---
|
||||
Hardware driver for the intel TCO timer based watchdog devices.
|
||||
These drivers are included in the Intel 82801 I/O Controller
|
||||
Hub family 'from ICH0 up to ICH7) and in the Intel 6300ESB
|
||||
Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB
|
||||
controller hub.
|
||||
|
||||
The TCO (Total Cost of Ownership) timer is a watchdog timer
|
||||
|
|
@ -395,6 +398,26 @@ config CPU5_WDT
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called cpu5wdt.
|
||||
|
||||
config SMSC37B787_WDT
|
||||
tristate "Winbond SMsC37B787 Watchdog Timer"
|
||||
depends on WATCHDOG && X86
|
||||
---help---
|
||||
This is the driver for the hardware watchdog component on the
|
||||
Winbond SMsC37B787 chipset as used on the NetRunner Mainboard
|
||||
from Vision Systems and maybe others.
|
||||
|
||||
This watchdog simply watches your kernel to make sure it doesn't
|
||||
freeze, and if it does, it reboots your computer after a certain
|
||||
amount of time.
|
||||
|
||||
Usually a userspace daemon will notify the kernel WDT driver that
|
||||
userspace is still alive, at regular intervals.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called smsc37b787_wdt.
|
||||
|
||||
Most people will say N.
|
||||
|
||||
config W83627HF_WDT
|
||||
tristate "W83627HF Watchdog Timer"
|
||||
depends on WATCHDOG && X86
|
||||
|
|
@ -410,6 +433,21 @@ config W83627HF_WDT
|
|||
|
||||
Most people will say N.
|
||||
|
||||
config W83697HF_WDT
|
||||
tristate "W83697HF/W83697HG Watchdog Timer"
|
||||
depends on WATCHDOG && X86
|
||||
---help---
|
||||
This is the driver for the hardware watchdog on the W83697HF/HG
|
||||
chipset as used in Dedibox/VIA motherboards (and likely others).
|
||||
This watchdog simply watches your kernel to make sure it doesn't
|
||||
freeze, and if it does, it reboots your computer after a certain
|
||||
amount of time.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called w83697hf_wdt.
|
||||
|
||||
Most people will say N.
|
||||
|
||||
config W83877F_WDT
|
||||
tristate "W83877F (EMACS) Watchdog Timer"
|
||||
depends on WATCHDOG && X86
|
||||
|
|
@ -443,7 +481,7 @@ config MACHZ_WDT
|
|||
depends on WATCHDOG && X86
|
||||
---help---
|
||||
If you are using a ZF Micro MachZ processor, say Y here, otherwise
|
||||
N. This is the driver for the watchdog timer builtin on that
|
||||
N. This is the driver for the watchdog timer built-in on that
|
||||
processor using ZF-Logic interface. This watchdog simply watches
|
||||
your kernel to make sure it doesn't freeze, and if it does, it
|
||||
reboots your computer after a certain amount of time.
|
||||
|
|
@ -472,7 +510,6 @@ config SBC_EPX_C3_WATCHDOG
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called sbc_epx_c3.
|
||||
|
||||
|
||||
# PowerPC Architecture
|
||||
|
||||
config 8xx_WDT
|
||||
|
|
@ -502,7 +539,7 @@ config WATCHDOG_RTAS
|
|||
help
|
||||
This driver adds watchdog support for the RTAS watchdog.
|
||||
|
||||
To compile this driver as a module, choose M here. The module
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called wdrtas.
|
||||
|
||||
# MIPS Architecture
|
||||
|
|
@ -556,7 +593,7 @@ config SH_WDT_MMAP
|
|||
help
|
||||
If you say Y here, user applications will be able to mmap the
|
||||
WDT/CPG registers.
|
||||
#
|
||||
|
||||
# SPARC64 Architecture
|
||||
|
||||
config WATCHDOG_CP1XXX
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ obj-$(CONFIG_WDTPCI) += wdt_pci.o
|
|||
obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
|
||||
|
||||
# ARM Architecture
|
||||
obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
|
||||
obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
|
||||
obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
|
||||
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
|
||||
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
|
||||
|
|
@ -53,7 +53,9 @@ obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
|
|||
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
|
||||
obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
|
||||
obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
|
||||
obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o
|
||||
obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
|
||||
obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o
|
||||
obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
|
||||
obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
|
||||
obj-$(CONFIG_MACHZ_WDT) += machzwd.o
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ static struct pci_dev *alim7101_pmu;
|
|||
|
||||
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||
module_param(nowayout, int, 0);
|
||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
|
||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||
__stringify(CONFIG_WATCHDOG_NOWAYOUT) ")");
|
||||
|
||||
/*
|
||||
* Whack the dog
|
||||
|
|
@ -415,6 +416,16 @@ err_out:
|
|||
module_init(alim7101_wdt_init);
|
||||
module_exit(alim7101_wdt_unload);
|
||||
|
||||
static struct pci_device_id alim7101_pci_tbl[] __devinitdata = {
|
||||
{ PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{ PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, alim7101_pci_tbl);
|
||||
|
||||
MODULE_AUTHOR("Steve Hill");
|
||||
MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
* 82801GDH (ICH7DH) : document number 307013-002, 307014-009,
|
||||
* 82801GBM (ICH7-M) : document number 307013-002, 307014-009,
|
||||
* 82801GHM (ICH7-M DH) : document number 307013-002, 307014-009,
|
||||
* 82801HB (ICH8) : document number 313056-002, 313057-004,
|
||||
* 82801HR (ICH8R) : document number 313056-002, 313057-004,
|
||||
* 82801HH (ICH8DH) : document number 313056-002, 313057-004,
|
||||
* 82801HO (ICH8DO) : document number 313056-002, 313057-004,
|
||||
* 6300ESB (6300ESB) : document number 300641-003
|
||||
*/
|
||||
|
||||
|
|
@ -45,7 +49,7 @@
|
|||
/* Module and version information */
|
||||
#define DRV_NAME "iTCO_wdt"
|
||||
#define DRV_VERSION "1.00"
|
||||
#define DRV_RELDATE "30-Jul-2006"
|
||||
#define DRV_RELDATE "08-Oct-2006"
|
||||
#define PFX DRV_NAME ": "
|
||||
|
||||
/* Includes */
|
||||
|
|
@ -85,6 +89,9 @@ enum iTCO_chipsets {
|
|||
TCO_ICH7, /* ICH7 & ICH7R */
|
||||
TCO_ICH7M, /* ICH7-M */
|
||||
TCO_ICH7MDH, /* ICH7-M DH */
|
||||
TCO_ICH8, /* ICH8 & ICH8R */
|
||||
TCO_ICH8DH, /* ICH8DH */
|
||||
TCO_ICH8DO, /* ICH8DO */
|
||||
};
|
||||
|
||||
static struct {
|
||||
|
|
@ -108,6 +115,9 @@ static struct {
|
|||
{"ICH7 or ICH7R", 2},
|
||||
{"ICH7-M", 2},
|
||||
{"ICH7-M DH", 2},
|
||||
{"ICH8 or ICH8R", 2},
|
||||
{"ICH8DH", 2},
|
||||
{"ICH8DO", 2},
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
|
|
@ -135,6 +145,9 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
|
|||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7 },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO },
|
||||
{ 0, }, /* End of list */
|
||||
};
|
||||
MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
|
||||
|
|
@ -355,7 +368,8 @@ static int iTCO_wdt_get_timeleft (int *time_left)
|
|||
spin_unlock(&iTCO_wdt_private.io_lock);
|
||||
|
||||
*time_left = (val8 * 6) / 10;
|
||||
}
|
||||
} else
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -426,7 +440,6 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
|
|||
{
|
||||
int new_options, retval = -EINVAL;
|
||||
int new_heartbeat;
|
||||
int time_left;
|
||||
void __user *argp = (void __user *)arg;
|
||||
int __user *p = argp;
|
||||
static struct watchdog_info ident = {
|
||||
|
|
@ -486,6 +499,8 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
|
|||
|
||||
case WDIOC_GETTIMELEFT:
|
||||
{
|
||||
int time_left;
|
||||
|
||||
if (iTCO_wdt_get_timeleft(&time_left))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -380,18 +380,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
|
|||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (res == NULL) {
|
||||
printk(KERN_INFO PFX "failed to get irq resource\n");
|
||||
iounmap(wdt_base);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
|
||||
if (ret != 0) {
|
||||
printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
|
||||
iounmap(wdt_base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wdt_clock = clk_get(&pdev->dev, "watchdog");
|
||||
if (wdt_clock == NULL) {
|
||||
printk(KERN_INFO PFX "failed to find watchdog clock source\n");
|
||||
iounmap(wdt_base);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
|
@ -415,6 +418,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
|
|||
if (ret) {
|
||||
printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
|
||||
WATCHDOG_MINOR, ret);
|
||||
iounmap(wdt_base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -451,6 +455,7 @@ static int s3c2410wdt_remove(struct platform_device *dev)
|
|||
wdt_clock = NULL;
|
||||
}
|
||||
|
||||
iounmap(wdt_base);
|
||||
misc_deregister(&s3c2410wdt_miscdev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void)
|
|||
if (io == -1) {
|
||||
printk(KERN_ERR PFX "io parameter must be specified\n");
|
||||
ret = -EINVAL;
|
||||
goto out_clean;
|
||||
goto out_pnp;
|
||||
}
|
||||
|
||||
#if defined CONFIG_PNP
|
||||
|
|
@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void)
|
|||
if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
|
||||
printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
|
||||
ret = -EBUSY;
|
||||
goto out_clean;
|
||||
goto out_pnp;
|
||||
}
|
||||
|
||||
ret = sc1200wdt_probe();
|
||||
|
|
@ -435,6 +435,11 @@ out_rbt:
|
|||
out_io:
|
||||
release_region(io, io_len);
|
||||
|
||||
out_pnp:
|
||||
#if defined CONFIG_PNP
|
||||
if (isapnp)
|
||||
pnp_unregister_driver(&scl200wdt_pnp_driver);
|
||||
#endif
|
||||
goto out_clean;
|
||||
}
|
||||
|
||||
|
|
|
|||
627
drivers/char/watchdog/smsc37b787_wdt.c
Normal file
627
drivers/char/watchdog/smsc37b787_wdt.c
Normal file
|
|
@ -0,0 +1,627 @@
|
|||
/*
|
||||
* SMsC 37B787 Watchdog Timer driver for Linux 2.6.x.x
|
||||
*
|
||||
* Based on acquirewdt.c by Alan Cox <alan@redhat.com>
|
||||
* and some other existing drivers
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* The authors do NOT admit liability nor provide warranty for
|
||||
* any of this software. This material is provided "AS-IS" in
|
||||
* the hope that it may be useful for others.
|
||||
*
|
||||
* (C) Copyright 2003-2006 Sven Anders <anders@anduras.de>
|
||||
*
|
||||
* History:
|
||||
* 2003 - Created version 1.0 for Linux 2.4.x.
|
||||
* 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE
|
||||
* features. Released version 1.1
|
||||
*
|
||||
* Theory of operation:
|
||||
*
|
||||
* A Watchdog Timer (WDT) is a hardware circuit that can
|
||||
* reset the computer system in case of a software fault.
|
||||
* You probably knew that already.
|
||||
*
|
||||
* Usually a userspace daemon will notify the kernel WDT driver
|
||||
* via the /dev/watchdog special device file that userspace is
|
||||
* still alive, at regular intervals. When such a notification
|
||||
* occurs, the driver will usually tell the hardware watchdog
|
||||
* that everything is in order, and that the watchdog should wait
|
||||
* for yet another little while to reset the system.
|
||||
* If userspace fails (RAM error, kernel bug, whatever), the
|
||||
* notifications cease to occur, and the hardware watchdog will
|
||||
* reset the system (causing a reboot) after the timeout occurs.
|
||||
*
|
||||
* Create device with:
|
||||
* mknod /dev/watchdog c 10 130
|
||||
*
|
||||
* For an example userspace keep-alive daemon, see:
|
||||
* Documentation/watchdog/watchdog.txt
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
/* enable support for minutes as units? */
|
||||
/* (does not always work correctly, so disabled by default!) */
|
||||
#define SMSC_SUPPORT_MINUTES
|
||||
#undef SMSC_SUPPORT_MINUTES
|
||||
|
||||
#define MAX_TIMEOUT 255
|
||||
|
||||
#define UNIT_SECOND 0
|
||||
#define UNIT_MINUTE 1
|
||||
|
||||
#define MODNAME "smsc37b787_wdt: "
|
||||
#define VERSION "1.1"
|
||||
|
||||
#define IOPORT 0x3F0
|
||||
#define IOPORT_SIZE 2
|
||||
#define IODEV_NO 8
|
||||
|
||||
static int unit = UNIT_SECOND; /* timer's unit */
|
||||
static int timeout = 60; /* timeout value: default is 60 "units" */
|
||||
static unsigned long timer_enabled = 0; /* is the timer enabled? */
|
||||
|
||||
static char expect_close; /* is the close expected? */
|
||||
|
||||
static spinlock_t io_lock; /* to guard the watchdog from io races */
|
||||
|
||||
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||
|
||||
/* -- Low level function ----------------------------------------*/
|
||||
|
||||
/* unlock the IO chip */
|
||||
|
||||
static inline void open_io_config(void)
|
||||
{
|
||||
outb(0x55, IOPORT);
|
||||
mdelay(1);
|
||||
outb(0x55, IOPORT);
|
||||
}
|
||||
|
||||
/* lock the IO chip */
|
||||
static inline void close_io_config(void)
|
||||
{
|
||||
outb(0xAA, IOPORT);
|
||||
}
|
||||
|
||||
/* select the IO device */
|
||||
static inline void select_io_device(unsigned char devno)
|
||||
{
|
||||
outb(0x07, IOPORT);
|
||||
outb(devno, IOPORT+1);
|
||||
}
|
||||
|
||||
/* write to the control register */
|
||||
static inline void write_io_cr(unsigned char reg, unsigned char data)
|
||||
{
|
||||
outb(reg, IOPORT);
|
||||
outb(data, IOPORT+1);
|
||||
}
|
||||
|
||||
/* read from the control register */
|
||||
static inline char read_io_cr(unsigned char reg)
|
||||
{
|
||||
outb(reg, IOPORT);
|
||||
return inb(IOPORT+1);
|
||||
}
|
||||
|
||||
/* -- Medium level functions ------------------------------------*/
|
||||
|
||||
static inline void gpio_bit12(unsigned char reg)
|
||||
{
|
||||
// -- General Purpose I/O Bit 1.2 --
|
||||
// Bit 0, In/Out: 0 = Output, 1 = Input
|
||||
// Bit 1, Polarity: 0 = No Invert, 1 = Invert
|
||||
// Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
|
||||
// Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17,
|
||||
// 11 = Either Edge Triggered Intr. 2
|
||||
// Bit 5/6 (Reserved)
|
||||
// Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
|
||||
write_io_cr(0xE2, reg);
|
||||
}
|
||||
|
||||
static inline void gpio_bit13(unsigned char reg)
|
||||
{
|
||||
// -- General Purpose I/O Bit 1.3 --
|
||||
// Bit 0, In/Out: 0 = Output, 1 = Input
|
||||
// Bit 1, Polarity: 0 = No Invert, 1 = Invert
|
||||
// Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
|
||||
// Bit 3, Function select: 0 = GPI/O, 1 = LED
|
||||
// Bit 4-6 (Reserved)
|
||||
// Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
|
||||
write_io_cr(0xE3, reg);
|
||||
}
|
||||
|
||||
static inline void wdt_timer_units(unsigned char new_units)
|
||||
{
|
||||
// -- Watchdog timer units --
|
||||
// Bit 0-6 (Reserved)
|
||||
// Bit 7, WDT Time-out Value Units Select
|
||||
// (0 = Minutes, 1 = Seconds)
|
||||
write_io_cr(0xF1, new_units);
|
||||
}
|
||||
|
||||
static inline void wdt_timeout_value(unsigned char new_timeout)
|
||||
{
|
||||
// -- Watchdog Timer Time-out Value --
|
||||
// Bit 0-7 Binary coded units (0=Disabled, 1..255)
|
||||
write_io_cr(0xF2, new_timeout);
|
||||
}
|
||||
|
||||
static inline void wdt_timer_conf(unsigned char conf)
|
||||
{
|
||||
// -- Watchdog timer configuration --
|
||||
// Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O
|
||||
// Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr.
|
||||
// Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr.
|
||||
// Bit 3 Reset the timer
|
||||
// (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled)
|
||||
// Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled,
|
||||
// 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15)
|
||||
write_io_cr(0xF3, conf);
|
||||
}
|
||||
|
||||
static inline void wdt_timer_ctrl(unsigned char reg)
|
||||
{
|
||||
// -- Watchdog timer control --
|
||||
// Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured
|
||||
// Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz
|
||||
// Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning)
|
||||
// Bit 3 P20 Force Timeout enabled:
|
||||
// 0 = P20 activity does not generate the WD timeout event
|
||||
// 1 = P20 Allows rising edge of P20, from the keyboard
|
||||
// controller, to force the WD timeout event.
|
||||
// Bit 4 (Reserved)
|
||||
// -- Soft power management --
|
||||
// Bit 5 Stop Counter: 1 = Stop software power down counter
|
||||
// set via register 0xB8, (self-cleaning)
|
||||
// (Upon read: 0 = Counter running, 1 = Counter stopped)
|
||||
// Bit 6 Restart Counter: 1 = Restart software power down counter
|
||||
// set via register 0xB8, (self-cleaning)
|
||||
// Bit 7 SPOFF: 1 = Force software power down (self-cleaning)
|
||||
|
||||
write_io_cr(0xF4, reg);
|
||||
}
|
||||
|
||||
/* -- Higher level functions ------------------------------------*/
|
||||
|
||||
/* initialize watchdog */
|
||||
|
||||
static void wb_smsc_wdt_initialize(void)
|
||||
{
|
||||
unsigned char old;
|
||||
|
||||
spin_lock(&io_lock);
|
||||
open_io_config();
|
||||
select_io_device(IODEV_NO);
|
||||
|
||||
// enable the watchdog
|
||||
gpio_bit13(0x08); // Select pin 80 = LED not GPIO
|
||||
gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert
|
||||
|
||||
// disable the timeout
|
||||
wdt_timeout_value(0);
|
||||
|
||||
// reset control register
|
||||
wdt_timer_ctrl(0x00);
|
||||
|
||||
// reset configuration register
|
||||
wdt_timer_conf(0x00);
|
||||
|
||||
// read old (timer units) register
|
||||
old = read_io_cr(0xF1) & 0x7F;
|
||||
if (unit == UNIT_SECOND) old |= 0x80; // set to seconds
|
||||
|
||||
// set the watchdog timer units
|
||||
wdt_timer_units(old);
|
||||
|
||||
close_io_config();
|
||||
spin_unlock(&io_lock);
|
||||
}
|
||||
|
||||
/* shutdown the watchdog */
|
||||
|
||||
static void wb_smsc_wdt_shutdown(void)
|
||||
{
|
||||
spin_lock(&io_lock);
|
||||
open_io_config();
|
||||
select_io_device(IODEV_NO);
|
||||
|
||||
// disable the watchdog
|
||||
gpio_bit13(0x09);
|
||||
gpio_bit12(0x09);
|
||||
|
||||
// reset watchdog config register
|
||||
wdt_timer_conf(0x00);
|
||||
|
||||
// reset watchdog control register
|
||||
wdt_timer_ctrl(0x00);
|
||||
|
||||
// disable timeout
|
||||
wdt_timeout_value(0x00);
|
||||
|
||||
close_io_config();
|
||||
spin_unlock(&io_lock);
|
||||
}
|
||||
|
||||
/* set timeout => enable watchdog */
|
||||
|
||||
static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
|
||||
{
|
||||
spin_lock(&io_lock);
|
||||
open_io_config();
|
||||
select_io_device(IODEV_NO);
|
||||
|
||||
// set Power LED to blink, if we enable the timeout
|
||||
wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02);
|
||||
|
||||
// set timeout value
|
||||
wdt_timeout_value(new_timeout);
|
||||
|
||||
close_io_config();
|
||||
spin_unlock(&io_lock);
|
||||
}
|
||||
|
||||
/* get timeout */
|
||||
|
||||
static unsigned char wb_smsc_wdt_get_timeout(void)
|
||||
{
|
||||
unsigned char set_timeout;
|
||||
|
||||
spin_lock(&io_lock);
|
||||
open_io_config();
|
||||
select_io_device(IODEV_NO);
|
||||
set_timeout = read_io_cr(0xF2);
|
||||
close_io_config();
|
||||
spin_unlock(&io_lock);
|
||||
|
||||
return set_timeout;
|
||||
}
|
||||
|
||||
/* disable watchdog */
|
||||
|
||||
static void wb_smsc_wdt_disable(void)
|
||||
{
|
||||
// set the timeout to 0 to disable the watchdog
|
||||
wb_smsc_wdt_set_timeout(0);
|
||||
}
|
||||
|
||||
/* enable watchdog by setting the current timeout */
|
||||
|
||||
static void wb_smsc_wdt_enable(void)
|
||||
{
|
||||
// set the current timeout...
|
||||
wb_smsc_wdt_set_timeout(timeout);
|
||||
}
|
||||
|
||||
/* reset the timer */
|
||||
|
||||
static void wb_smsc_wdt_reset_timer(void)
|
||||
{
|
||||
spin_lock(&io_lock);
|
||||
open_io_config();
|
||||
select_io_device(IODEV_NO);
|
||||
|
||||
// reset the timer
|
||||
wdt_timeout_value(timeout);
|
||||
wdt_timer_conf(0x08);
|
||||
|
||||
close_io_config();
|
||||
spin_unlock(&io_lock);
|
||||
}
|
||||
|
||||
/* return, if the watchdog is enabled (timeout is set...) */
|
||||
|
||||
static int wb_smsc_wdt_status(void)
|
||||
{
|
||||
return (wb_smsc_wdt_get_timeout() == 0) ? 0 : WDIOF_KEEPALIVEPING;
|
||||
}
|
||||
|
||||
|
||||
/* -- File operations -------------------------------------------*/
|
||||
|
||||
/* open => enable watchdog and set initial timeout */
|
||||
|
||||
static int wb_smsc_wdt_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
/* /dev/watchdog can only be opened once */
|
||||
|
||||
if (test_and_set_bit(0, &timer_enabled))
|
||||
return -EBUSY;
|
||||
|
||||
if (nowayout)
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
/* Reload and activate timer */
|
||||
wb_smsc_wdt_enable();
|
||||
|
||||
printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
|
||||
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
/* close => shut off the timer */
|
||||
|
||||
static int wb_smsc_wdt_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
/* Shut off the timer. */
|
||||
|
||||
if (expect_close == 42) {
|
||||
wb_smsc_wdt_disable();
|
||||
printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n");
|
||||
} else {
|
||||
printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n");
|
||||
wb_smsc_wdt_reset_timer();
|
||||
}
|
||||
|
||||
clear_bit(0, &timer_enabled);
|
||||
expect_close = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write => update the timer to keep the machine alive */
|
||||
|
||||
static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
|
||||
size_t len, loff_t *ppos)
|
||||
{
|
||||
/* See if we got the magic character 'V' and reload the timer */
|
||||
if (len) {
|
||||
if (!nowayout) {
|
||||
size_t i;
|
||||
|
||||
/* reset expect flag */
|
||||
expect_close = 0;
|
||||
|
||||
/* scan to see whether or not we got the magic character */
|
||||
for (i = 0; i != len; i++) {
|
||||
char c;
|
||||
if (get_user(c, data+i))
|
||||
return -EFAULT;
|
||||
if (c == 'V')
|
||||
expect_close = 42;
|
||||
}
|
||||
}
|
||||
|
||||
/* someone wrote to us, we should reload the timer */
|
||||
wb_smsc_wdt_reset_timer();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ioctl => control interface */
|
||||
|
||||
static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int new_timeout;
|
||||
|
||||
union {
|
||||
struct watchdog_info __user *ident;
|
||||
int __user *i;
|
||||
} uarg;
|
||||
|
||||
static struct watchdog_info ident = {
|
||||
.options = WDIOF_KEEPALIVEPING |
|
||||
WDIOF_SETTIMEOUT |
|
||||
WDIOF_MAGICCLOSE,
|
||||
.firmware_version = 0,
|
||||
.identity = "SMsC 37B787 Watchdog"
|
||||
};
|
||||
|
||||
uarg.i = (int __user *)arg;
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
return -ENOTTY;
|
||||
|
||||
case WDIOC_GETSUPPORT:
|
||||
return copy_to_user(uarg.ident, &ident,
|
||||
sizeof(ident)) ? -EFAULT : 0;
|
||||
|
||||
case WDIOC_GETSTATUS:
|
||||
return put_user(wb_smsc_wdt_status(), uarg.i);
|
||||
|
||||
case WDIOC_GETBOOTSTATUS:
|
||||
return put_user(0, uarg.i);
|
||||
|
||||
case WDIOC_KEEPALIVE:
|
||||
wb_smsc_wdt_reset_timer();
|
||||
return 0;
|
||||
|
||||
case WDIOC_SETTIMEOUT:
|
||||
if (get_user(new_timeout, uarg.i))
|
||||
return -EFAULT;
|
||||
|
||||
// the API states this is given in secs
|
||||
if (unit == UNIT_MINUTE)
|
||||
new_timeout /= 60;
|
||||
|
||||
if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
|
||||
return -EINVAL;
|
||||
|
||||
timeout = new_timeout;
|
||||
wb_smsc_wdt_set_timeout(timeout);
|
||||
|
||||
// fall through and return the new timeout...
|
||||
|
||||
case WDIOC_GETTIMEOUT:
|
||||
|
||||
new_timeout = timeout;
|
||||
|
||||
if (unit == UNIT_MINUTE)
|
||||
new_timeout *= 60;
|
||||
|
||||
return put_user(new_timeout, uarg.i);
|
||||
|
||||
case WDIOC_SETOPTIONS:
|
||||
{
|
||||
int options, retval = -EINVAL;
|
||||
|
||||
if (get_user(options, uarg.i))
|
||||
return -EFAULT;
|
||||
|
||||
if (options & WDIOS_DISABLECARD) {
|
||||
wb_smsc_wdt_disable();
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
if (options & WDIOS_ENABLECARD) {
|
||||
wb_smsc_wdt_enable();
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Notifier funtions -----------------------------------------*/
|
||||
|
||||
static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
|
||||
{
|
||||
if (code == SYS_DOWN || code == SYS_HALT)
|
||||
{
|
||||
// set timeout to 0, to avoid possible race-condition
|
||||
timeout = 0;
|
||||
wb_smsc_wdt_disable();
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/* -- Module's structures ---------------------------------------*/
|
||||
|
||||
static struct file_operations wb_smsc_wdt_fops =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.write = wb_smsc_wdt_write,
|
||||
.ioctl = wb_smsc_wdt_ioctl,
|
||||
.open = wb_smsc_wdt_open,
|
||||
.release = wb_smsc_wdt_release,
|
||||
};
|
||||
|
||||
static struct notifier_block wb_smsc_wdt_notifier =
|
||||
{
|
||||
.notifier_call = wb_smsc_wdt_notify_sys,
|
||||
};
|
||||
|
||||
static struct miscdevice wb_smsc_wdt_miscdev =
|
||||
{
|
||||
.minor = WATCHDOG_MINOR,
|
||||
.name = "watchdog",
|
||||
.fops = &wb_smsc_wdt_fops,
|
||||
};
|
||||
|
||||
/* -- Module init functions -------------------------------------*/
|
||||
|
||||
/* module's "constructor" */
|
||||
|
||||
static int __init wb_smsc_wdt_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
spin_lock_init(&io_lock);
|
||||
|
||||
printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n");
|
||||
|
||||
if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) {
|
||||
printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT);
|
||||
ret = -EBUSY;
|
||||
goto out_pnp;
|
||||
}
|
||||
|
||||
// set new maximum, if it's too big
|
||||
if (timeout > MAX_TIMEOUT)
|
||||
timeout = MAX_TIMEOUT;
|
||||
|
||||
// init the watchdog timer
|
||||
wb_smsc_wdt_initialize();
|
||||
|
||||
ret = register_reboot_notifier(&wb_smsc_wdt_notifier);
|
||||
if (ret) {
|
||||
printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret);
|
||||
goto out_io;
|
||||
}
|
||||
|
||||
ret = misc_register(&wb_smsc_wdt_miscdev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR);
|
||||
goto out_rbt;
|
||||
}
|
||||
|
||||
// output info
|
||||
printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
|
||||
printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout);
|
||||
|
||||
// ret = 0
|
||||
|
||||
out_clean:
|
||||
return ret;
|
||||
|
||||
out_rbt:
|
||||
unregister_reboot_notifier(&wb_smsc_wdt_notifier);
|
||||
|
||||
out_io:
|
||||
release_region(IOPORT, IOPORT_SIZE);
|
||||
|
||||
out_pnp:
|
||||
goto out_clean;
|
||||
}
|
||||
|
||||
/* module's "destructor" */
|
||||
|
||||
static void __exit wb_smsc_wdt_exit(void)
|
||||
{
|
||||
/* Stop the timer before we leave */
|
||||
if (!nowayout)
|
||||
{
|
||||
wb_smsc_wdt_shutdown();
|
||||
printk(KERN_INFO MODNAME "Watchdog disabled.\n");
|
||||
}
|
||||
|
||||
misc_deregister(&wb_smsc_wdt_miscdev);
|
||||
unregister_reboot_notifier(&wb_smsc_wdt_notifier);
|
||||
release_region(IOPORT, IOPORT_SIZE);
|
||||
|
||||
printk("SMsC 37B787 watchdog component driver removed.\n");
|
||||
}
|
||||
|
||||
module_init(wb_smsc_wdt_init);
|
||||
module_exit(wb_smsc_wdt_exit);
|
||||
|
||||
MODULE_AUTHOR("Sven Anders <[email protected]>");
|
||||
MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
||||
|
||||
#ifdef SMSC_SUPPORT_MINUTES
|
||||
module_param(unit, int, 0);
|
||||
MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0");
|
||||
#endif
|
||||
|
||||
module_param(timeout, int, 0);
|
||||
MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
|
||||
|
||||
module_param(nowayout, int, 0);
|
||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
|
||||
static unsigned long wdt_is_open;
|
||||
static char expect_close;
|
||||
static spinlock_t io_lock;
|
||||
|
||||
/* You must set this - there is no sane way to probe for this board. */
|
||||
static int wdt_io = 0x2E;
|
||||
|
|
@ -110,12 +112,16 @@ w83627hf_init(void)
|
|||
static void
|
||||
wdt_ctrl(int timeout)
|
||||
{
|
||||
spin_lock(&io_lock);
|
||||
|
||||
w83627hf_select_wd_register();
|
||||
|
||||
outb_p(0xF6, WDT_EFER); /* Select CRF6 */
|
||||
outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */
|
||||
|
||||
w83627hf_unselect_wd_register();
|
||||
|
||||
spin_unlock(&io_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -303,6 +309,8 @@ wdt_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
spin_lock_init(&io_lock);
|
||||
|
||||
printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n");
|
||||
|
||||
if (wdt_set_heartbeat(timeout)) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue