Commit 7176b206 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.12pre4

parent 77725b26
......@@ -188,7 +188,7 @@ tristate 'Kernel support for a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
source drivers/parpor/Config.in
source drivers/parport/Config.in
endmenu
source drivers/pnp/Config.in
......
......@@ -322,14 +322,9 @@ void machine_restart(char * __unused)
pg0[0] = _PAGE_RW | _PAGE_PRESENT;
/*
* Use `swapper_pg_dir' as our page directory. We bother with
* `SET_PAGE_DIR' because although might be rebooting, but if we change
* the way we set root page dir in the future, then we wont break a
* seldom used feature ;)
* Use `swapper_pg_dir' as our page directory.
*/
current->mm->pgd = swapper_pg_dir;
current->active_mm->pgd = swapper_pg_dir;
activate_context();
asm volatile("movl %0,%%cr3": :"r" (__pa(swapper_pg_dir)));
/* Write 0x1234 to absolute memory location 0x472. The BIOS reads
this on booting to tell it to "Bypass memory test (also warm
......@@ -490,16 +485,7 @@ void release_segments(struct mm_struct *mm)
*/
if (ldt) {
mm->segments = NULL;
/*
* special case, when we release the LDT from under
* the running CPU. Other CPUs cannot possibly use
* this LDT as we were getting here through mmput() ...
*/
if (mm == current->mm)
load_LDT(mm);
/*
* Nobody anymore uses the LDT, we can free it:
*/
clear_LDT();
vfree(ldt);
}
}
......@@ -581,12 +567,8 @@ void release_thread(struct task_struct *dead_task)
}
/*
* If new_mm is NULL, we're being called to set up the LDT for
* a clone task: this is easy since the clone is not running yet.
* otherwise we copy the old segment into a new segment.
*
* we do not have to muck with descriptors here, that is
* done in __switch_to() and get_mmu_context().
* done in switch_mm() as needed.
*/
void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
{
......@@ -597,22 +579,19 @@ void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
/*
* default LDT - use the one from init_task
*/
if (new_mm)
new_mm->segments = NULL;
new_mm->segments = NULL;
return;
}
if (new_mm) {
/*
* Completely new LDT, we initialize it from the parent:
*/
ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
if (!ldt)
printk(KERN_WARNING "ldt allocation failed\n");
else
memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
new_mm->segments = ldt;
}
/*
* Completely new LDT, we initialize it from the parent:
*/
ldt = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
if (!ldt)
printk(KERN_WARNING "ldt allocation failed\n");
else
memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
new_mm->segments = ldt;
return;
}
......
......@@ -336,15 +336,15 @@ int usb_mouse_init(void)
{
struct mouse_state *mouse = &static_mouse_state;
misc_register(&usb_mouse);
mouse->present = mouse->active = 0;
mouse->irq_handle = NULL;
init_waitqueue_head(&mouse->wait);
mouse->fasync = NULL;
misc_register(&usb_mouse);
usb_register(&mouse_driver);
printk(KERN_INFO "USB HID boot protocol mouse registered.\n");
printk(KERN_INFO "USB HID boot protocol mouse driver registered.\n");
return 0;
}
......
......@@ -131,7 +131,18 @@ void show_ohci_td(struct ohci_td *td)
printk(KERN_DEBUG " next_td = 0x%x\n", le32_to_cpup(&td->next_td));
printk(KERN_DEBUG " buf_end = 0x%x\n", le32_to_cpup(&td->buf_end));
printk(KERN_DEBUG " ohci TD driver fields:\n");
printk(KERN_DEBUG " flags = %x {", td->hcd_flags);
if (td_allocated(*td))
printk(" alloc");
if (td_dummy(*td))
printk(" dummy");
if (td_endofchain(*td))
printk(" endofchain");
if (!can_auto_free(*td))
printk(" noautofree");
printk("}\n");
printk(KERN_DEBUG " data = %p\n", td->data);
printk(KERN_DEBUG " cmpltd = %p\n", td->completed);
printk(KERN_DEBUG " dev_id = %p\n", td->dev_id);
printk(KERN_DEBUG " ed = %p\n", td->ed);
if (td->data != NULL) {
......
This diff is collapsed.
......@@ -41,8 +41,7 @@ struct ohci_td {
/* bit0: Is this TD allocated? */
/* bit1: Is this a dummy (end of list) TD? */
/* bit2: do NOT automatically free this TD on completion */
/* bit3: this is NOT the last TD in a contiguious TD chain
* on the indicated ED. (0 means it is the last) */
/* bit3: this is the last TD in a contiguious TD chain */
struct usb_device *usb_dev; /* the owning device */
......@@ -86,9 +85,9 @@ struct ohci_td {
#define make_dumb_td(td) ((td)->hcd_flags |= 2)
#define clear_dumb_td(td) ((td)->hcd_flags &= ~(__u32)2)
#define td_endofchain(td) (!((td).hcd_flags & (1 << 3)))
#define set_td_endofchain(td) ((td)->hcd_flags &= ~(1 << 3))
#define clear_td_endofchain(td) ((td)->hcd_flags |= (1 << 3))
#define td_endofchain(td) ((td).hcd_flags & (1 << 3))
#define clear_td_endofchain(td) ((td)->hcd_flags &= ~(1 << 3))
#define set_td_endofchain(td) ((td)->hcd_flags |= (1 << 3))
/*
* These control if the IRQ will call ohci_free_td after taking the TDs
......@@ -109,6 +108,10 @@ struct ohci_ed {
__u32 tail_td; /* TD Queue tail pointer */
__u32 _head_td; /* TD Queue head pointer, toggle carry & halted bits */
__u32 next_ed; /* Next ED */
/* driver fields */
struct ohci_device *ohci_dev;
struct ohci_ed *ed_chain;
} __attribute((aligned(16)));
/* get the head_td */
......@@ -119,10 +122,13 @@ struct ohci_ed {
#define set_ed_head_td(ed, td) ((ed)->_head_td = cpu_to_le32((td)) \
| ((ed)->_head_td & cpu_to_le32(3)))
/* Control the ED's halted flag */
/* Control the ED's halted and carry flags */
#define ohci_halt_ed(ed) ((ed)->_head_td |= cpu_to_le32(1))
#define ohci_unhalt_ed(ed) ((ed)->_head_td &= cpu_to_le32(~(__u32)1))
#define ohci_ed_halted(ed) ((ed)->_head_td & cpu_to_le32(1))
#define ohci_ed_set_carry(ed) ((ed)->_head_td |= cpu_to_le32(2))
#define ohci_ed_clr_carry(ed) ((ed)->_head_td &= ~cpu_to_le32(2))
#define ohci_ed_carry(ed) ((le32_to_cpup(&(ed)->_head_td) >> 1) & 1)
#define OHCI_ED_SKIP (1 << 14)
#define OHCI_ED_MPS (0x7ff << 16)
......@@ -142,6 +148,8 @@ struct ohci_ed {
#define OHCI_ED_EN (0xf << 7)
#define OHCI_ED_FA (0x7f)
#define ed_get_en(ed) ((le32_to_cpup(&(ed)->status) & OHCI_ED_EN) >> 7)
#define ed_get_fa(ed) (le32_to_cpup(&(ed)->status) & OHCI_ED_FA)
/* NOTE: bits 27-31 of the status dword are reserved for the HCD */
/*
......
......@@ -139,10 +139,20 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
this_xfer = length > max_size ? max_size : length;
length -= this_xfer;
do {
US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer);
/*US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer);*/
result = us->pusb_dev->bus->op->bulk_msg(us->pusb_dev, pipe, buf,
this_xfer, &partial);
if (result != 0 || partial != this_xfer)
US_DEBUGP("bulk_msg returned %d xferred %lu/%d\n",
result, partial, this_xfer);
if (result == USB_ST_STALL) {
US_DEBUGP("clearing endpoing halt for pipe %x\n", pipe);
usb_clear_halt(us->pusb_dev,
usb_pipeendpoint(pipe) | (pipe & 0x80));
}
/* we want to retry if the device reported NAK */
if (result == USB_ST_TIMEOUT) {
if (partial != this_xfer) {
......@@ -171,28 +181,31 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
return 0;
}
static int us_transfer(Scsi_Cmnd *srb, int dir_in)
{
struct us_data *us = (struct us_data *)srb->host_scribble;
int i;
int result = -1;
unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
usb_sndbulkpipe(us->pusb_dev, us->ep_out);
if (srb->use_sg) {
struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
for (i = 0; i < srb->use_sg; i++) {
result = us_one_transfer(us, dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
usb_sndbulkpipe(us->pusb_dev, us->ep_out),
sg[i].address, sg[i].length);
result = us_one_transfer(us, pipe, sg[i].address, sg[i].length);
if (result)
break;
}
return result;
}
else
return us_one_transfer(us, dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
usb_sndbulkpipe(us->pusb_dev, us->ep_out),
srb->request_buffer, srb->request_bufflen);
result = us_one_transfer(us, pipe,
srb->request_buffer, srb->request_bufflen);
if (result)
US_DEBUGP("us_transfer returning error %d\n", result);
return result;
}
static unsigned int us_transfer_length(Scsi_Cmnd *srb)
......@@ -232,12 +245,13 @@ static int pop_CBI_irq(int state, void *buffer, int len, void *dev_id)
struct us_data *us = (struct us_data *)dev_id;
if (state != USB_ST_REMOVED) {
us->ip_data = *(__u16 *)buffer;
US_DEBUGP("Interrupt Status %x\n", us->ip_data);
us->ip_data = le16_to_cpup((__u16 *)buffer);
/* US_DEBUGP("Interrupt Status %x\n", us->ip_data); */
}
if (us->ip_wanted)
if (us->ip_wanted) {
us->ip_wanted = 0;
wake_up(&us->ip_waitq);
us->ip_wanted = 0;
}
/* we dont want another interrupt */
......@@ -250,6 +264,7 @@ static int pop_CB_reset(struct us_data *us)
devrequest dr;
int result;
US_DEBUGP("pop_CB_reset\n");
dr.requesttype = USB_TYPE_CLASS | USB_RT_INTERFACE;
dr.request = US_CBI_ADSC;
dr.value = 0;
......@@ -262,12 +277,15 @@ static int pop_CB_reset(struct us_data *us)
usb_sndctrlpipe(us->pusb_dev,0),
&dr, cmd, 12);
usb_clear_halt(us->pusb_dev, us->ep_in | 0x80);
usb_clear_halt(us->pusb_dev, us->ep_out);
/* long wait for reset */
schedule_timeout(HZ*5);
US_DEBUGP("pop_CB_reset: clearing endpoint halt\n");
usb_clear_halt(us->pusb_dev, us->ep_in | 0x80);
usb_clear_halt(us->pusb_dev, us->ep_out);
US_DEBUGP("pop_CB_reset done\n");
return 0;
}
......@@ -325,6 +343,7 @@ static int pop_CB_command(Scsi_Cmnd *srb)
/* as per spec try a start command, wait and retry */
done_start++;
memset(cmd, 0, sizeof(cmd));
cmd[0] = START_STOP;
cmd[4] = 1; /* start */
result = us->pusb_dev->bus->op->control_msg(us->pusb_dev,
......@@ -338,7 +357,7 @@ static int pop_CB_command(Scsi_Cmnd *srb)
result = us->pusb_dev->bus->op->control_msg(us->pusb_dev,
usb_sndctrlpipe(us->pusb_dev,0),
&dr, srb->cmnd, srb->cmd_len);
if (result != USB_ST_STALL && result != USB_ST_TIMEOUT)
if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT)
return result;
}
return result;
......@@ -356,6 +375,7 @@ static int pop_CB_status(Scsi_Cmnd *srb)
devrequest dr;
int retry = 5;
US_DEBUGP("pop_CB_status, proto=%x\n", us->protocol);
switch (us->protocol) {
case US_PR_CB:
/* get from control */
......@@ -439,23 +459,26 @@ static int pop_CBI(Scsi_Cmnd *srb)
if (result == USB_ST_STALL || result == USB_ST_TIMEOUT) {
return (DID_OK << 16) | 2;
}
return DID_ABORT << 16;
return DID_ERROR << 16;
}
/* transfer the data */
if (us_transfer_length(srb)) {
result = us_transfer(srb, US_DIRECTION(srb->cmnd[0]));
if (result && result != USB_ST_DATAUNDERRUN) {
if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
US_DEBUGP("CBI transfer %x\n", result);
return DID_ABORT << 16;
} else if (result == USB_ST_DATAUNDERRUN) {
return DID_ERROR << 16;
}
#if 0
else if (result == USB_ST_DATAUNDERRUN) {
return DID_OK << 16;
}
} else {
if (!result) {
return DID_OK << 16;
}
#endif
}
/* get status */
......@@ -947,6 +970,7 @@ static int usbscsi_control_thread(void * __us)
US_DEBUGP("Old/New length = %d/%d\n", savelen, length);
if (us->srb->request_bufflen != length) {
US_DEBUGP("redoing cmd with len=%d\n", length);
us->srb->request_bufflen = length;
us->srb->result = us->pop(us->srb);
}
......@@ -957,6 +981,15 @@ static int usbscsi_control_thread(void * __us)
case REQUEST_SENSE:
case INQUIRY:
case MODE_SENSE:
if (us->srb->use_sg == 0 && length > 0) {
int i;
printk(KERN_DEBUG "Data is");
for (i = 0; i < 32 && i < length; ++i)
printk(" %.2x", ((unsigned char *)us->srb->request_buffer)[i]);
if (i < length)
printk(" ...");
printk("\n");
}
us->srb->cmnd[4] = saveallocation;
break;
......@@ -969,6 +1002,7 @@ static int usbscsi_control_thread(void * __us)
}
/* force attention on first command */
if (!us->attention_done) {
US_DEBUGP("forcing unit attention\n");
if (us->srb->cmnd[0] == REQUEST_SENSE) {
if (us->srb->result == (DID_OK << 16)) {
unsigned char *p = (unsigned char *)us->srb->request_buffer;
......@@ -987,6 +1021,7 @@ static int usbscsi_control_thread(void * __us)
}
}
}
US_DEBUGP("scsi cmd done, result=%x\n", us->srb->result);
us->srb->scsi_done(us->srb);
us->srb = NULL;
break;
......
......@@ -1972,7 +1972,7 @@ void end_lazy_tlb(struct mm_struct *mm)
current->mm = mm;
if (mm != active_mm) {
current->active_mm = mm;
activate_context();
switch_mm(active_mm, mm);
}
mmdrop(active_mm);
}
......
......@@ -384,7 +384,7 @@ static int exec_mmap(void)
mm->cpu_vm_mask = (1UL << smp_processor_id());
current->mm = mm;
current->active_mm = mm;
activate_context();
switch_mm(active_mm, mm);
mm_release();
if (old_mm) {
if (active_mm != old_mm) BUG();
......
......@@ -69,17 +69,28 @@ extern void set_intr_gate(unsigned int irq, void * addr);
extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
extern void set_tss_desc(unsigned int n, void *addr);
extern inline void clear_LDT(void)
{
int cpu = smp_processor_id();
set_ldt_desc(cpu, &default_ldt, 1);
__load_LDT(cpu);
}
/*
* load one particular LDT into the current CPU
*/
extern inline void load_LDT (struct mm_struct *mm)
{
int cpu = smp_processor_id();
void *segments = mm->segments;
int count = LDT_ENTRIES;
if (mm->segments)
set_ldt_desc(cpu, mm->segments, LDT_ENTRIES);
else
set_ldt_desc(cpu, &default_ldt, 1);
if (!segments) {
segments = &default_ldt;
count = 1;
}
set_ldt_desc(cpu, segments, count);
__load_LDT(cpu);
}
......
......@@ -9,15 +9,6 @@
#define destroy_context(mm) do { } while(0)
#define init_new_context(tsk,mm) do { } while (0)
static inline void activate_context(void)
{
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
load_LDT(mm);
__asm__ __volatile__("movl %0,%%cr3": :"r" (__pa(mm->pgd)));
}
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next)
{
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment