mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 15:41:36 +00:00
Merge branch 'release' of master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6
This commit is contained in:
commit
e53897e2fb
@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
|
||||
simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
|
||||
}
|
||||
|
||||
static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
|
||||
{
|
||||
|
||||
int scatterlen = sc->use_sg;
|
||||
struct scatterlist *slp;
|
||||
|
||||
if (scatterlen == 0)
|
||||
memcpy(sc->request_buffer, buf, len);
|
||||
else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) {
|
||||
unsigned thislen = min(len, slp->length);
|
||||
|
||||
memcpy(page_address(slp->page) + slp->offset, buf, thislen);
|
||||
slp++;
|
||||
len -= thislen;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
char fname[MAX_ROOT_LEN+16];
|
||||
size_t disk_size;
|
||||
char *buf;
|
||||
char localbuf[36];
|
||||
#if DEBUG_SIMSCSI
|
||||
register long sp asm ("sp");
|
||||
|
||||
@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
/* disk doesn't exist... */
|
||||
break;
|
||||
}
|
||||
buf = sc->request_buffer;
|
||||
buf = localbuf;
|
||||
buf[0] = 0; /* magnetic disk */
|
||||
buf[1] = 0; /* not a removable medium */
|
||||
buf[2] = 2; /* SCSI-2 compliant device */
|
||||
@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
buf[6] = 0; /* reserved */
|
||||
buf[7] = 0; /* various flags */
|
||||
memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28);
|
||||
simscsi_fillresult(sc, buf, 36);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
simscsi_readwrite10(sc, SSC_WRITE);
|
||||
break;
|
||||
|
||||
|
||||
case READ_CAPACITY:
|
||||
if (desc[target_id] < 0 || sc->request_bufflen < 8) {
|
||||
break;
|
||||
}
|
||||
buf = sc->request_buffer;
|
||||
|
||||
buf = localbuf;
|
||||
disk_size = simscsi_get_disk_size(desc[target_id]);
|
||||
|
||||
/* pretend to be a 1GB disk (partition table contains real stuff): */
|
||||
buf[0] = (disk_size >> 24) & 0xff;
|
||||
buf[1] = (disk_size >> 16) & 0xff;
|
||||
buf[2] = (disk_size >> 8) & 0xff;
|
||||
@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
||||
buf[5] = 0;
|
||||
buf[6] = 2;
|
||||
buf[7] = 0;
|
||||
simscsi_fillresult(sc, buf, 8);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
case MODE_SENSE:
|
||||
case MODE_SENSE_10:
|
||||
/* sd.c uses this to determine whether disk does write-caching. */
|
||||
memset(sc->request_buffer, 0, 128);
|
||||
simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen);
|
||||
sc->result = GOOD;
|
||||
break;
|
||||
|
||||
|
@ -489,24 +489,27 @@ ia64_state_save:
|
||||
;;
|
||||
st8 [temp1]=r17,16 // pal_min_state
|
||||
st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT
|
||||
mov r6=IA64_KR(CURRENT_STACK)
|
||||
;;
|
||||
st8 [temp1]=r6,16 // prev_IA64_KR_CURRENT_STACK
|
||||
st8 [temp2]=r0,16 // prev_task, starts off as NULL
|
||||
mov r6=cr.ifa
|
||||
;;
|
||||
st8 [temp1]=r0,16 // prev_task, starts off as NULL
|
||||
st8 [temp2]=r12,16 // cr.isr
|
||||
st8 [temp1]=r12,16 // cr.isr
|
||||
st8 [temp2]=r6,16 // cr.ifa
|
||||
mov r12=cr.itir
|
||||
;;
|
||||
st8 [temp1]=r6,16 // cr.ifa
|
||||
st8 [temp2]=r12,16 // cr.itir
|
||||
st8 [temp1]=r12,16 // cr.itir
|
||||
st8 [temp2]=r11,16 // cr.iipa
|
||||
mov r12=cr.iim
|
||||
;;
|
||||
st8 [temp1]=r11,16 // cr.iipa
|
||||
st8 [temp2]=r12,16 // cr.iim
|
||||
mov r6=cr.iha
|
||||
st8 [temp1]=r12,16 // cr.iim
|
||||
(p1) mov r12=IA64_MCA_COLD_BOOT
|
||||
(p2) mov r12=IA64_INIT_WARM_BOOT
|
||||
mov r6=cr.iha
|
||||
;;
|
||||
st8 [temp1]=r6,16 // cr.iha
|
||||
st8 [temp2]=r12 // os_status, default is cold boot
|
||||
st8 [temp2]=r6,16 // cr.iha
|
||||
st8 [temp1]=r12 // os_status, default is cold boot
|
||||
mov r6=IA64_MCA_SAME_CONTEXT
|
||||
;;
|
||||
st8 [temp1]=r6 // context, default is same context
|
||||
@ -823,9 +826,12 @@ ia64_state_restore:
|
||||
ld8 r12=[temp1],16 // sal_ra
|
||||
ld8 r9=[temp2],16 // sal_gp
|
||||
;;
|
||||
ld8 r22=[temp1],24 // pal_min_state, virtual. skip prev_task
|
||||
ld8 r22=[temp1],16 // pal_min_state, virtual
|
||||
ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT
|
||||
;;
|
||||
ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK
|
||||
ld8 r20=[temp2],16 // prev_task
|
||||
;;
|
||||
ld8 temp3=[temp1],16 // cr.isr
|
||||
ld8 temp4=[temp2],16 // cr.ifa
|
||||
;;
|
||||
@ -846,6 +852,45 @@ ia64_state_restore:
|
||||
ld8 r8=[temp1] // os_status
|
||||
ld8 r10=[temp2] // context
|
||||
|
||||
/* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to. To
|
||||
* avoid any dependencies on the algorithm in ia64_switch_to(), just
|
||||
* purge any existing CURRENT_STACK mapping and insert the new one.
|
||||
*
|
||||
* r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains
|
||||
* prev_IA64_KR_CURRENT, these values may have been changed by the C
|
||||
* code. Do not use r8, r9, r10, r22, they contain values ready for
|
||||
* the return to SAL.
|
||||
*/
|
||||
|
||||
mov r15=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
shl r15=r15,IA64_GRANULE_SHIFT
|
||||
;;
|
||||
dep r15=-1,r15,61,3 // virtual granule
|
||||
mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
|
||||
;;
|
||||
ptr.d r15,r18
|
||||
;;
|
||||
srlz.d
|
||||
|
||||
extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT
|
||||
shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK
|
||||
movl r21=PAGE_KERNEL // page properties
|
||||
;;
|
||||
mov IA64_KR(CURRENT_STACK)=r16
|
||||
cmp.ne p6,p0=RGN_KERNEL,r19 // new stack is in the kernel region?
|
||||
or r21=r20,r21 // construct PA | page properties
|
||||
(p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:(
|
||||
;;
|
||||
mov cr.itir=r18
|
||||
mov cr.ifa=r21
|
||||
mov r20=IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
itr.d dtr[r20]=r21
|
||||
;;
|
||||
srlz.d
|
||||
1:
|
||||
|
||||
br.sptk b0
|
||||
|
||||
//EndStub//////////////////////////////////////////////////////////////////////
|
||||
@ -982,6 +1027,7 @@ ia64_set_kernel_registers:
|
||||
add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp
|
||||
add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack
|
||||
add r13=temp1, r3 // set current to start of MCA/INIT stack
|
||||
add r20=temp1, r3 // physical start of MCA/INIT stack
|
||||
;;
|
||||
ld8 r1=[temp4] // OS GP from SAL OS state
|
||||
;;
|
||||
@ -991,7 +1037,35 @@ ia64_set_kernel_registers:
|
||||
;;
|
||||
mov IA64_KR(CURRENT)=r13
|
||||
|
||||
// FIXME: do I need to wire IA64_KR_CURRENT_STACK and IA64_TR_CURRENT_STACK?
|
||||
/* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack. To avoid
|
||||
* any dependencies on the algorithm in ia64_switch_to(), just purge
|
||||
* any existing CURRENT_STACK mapping and insert the new one.
|
||||
*/
|
||||
|
||||
mov r16=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
shl r16=r16,IA64_GRANULE_SHIFT
|
||||
;;
|
||||
dep r16=-1,r16,61,3 // virtual granule
|
||||
mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
|
||||
;;
|
||||
ptr.d r16,r18
|
||||
;;
|
||||
srlz.d
|
||||
|
||||
shr.u r16=r20,IA64_GRANULE_SHIFT // r20 = physical start of MCA/INIT stack
|
||||
movl r21=PAGE_KERNEL // page properties
|
||||
;;
|
||||
mov IA64_KR(CURRENT_STACK)=r16
|
||||
or r21=r20,r21 // construct PA | page properties
|
||||
;;
|
||||
mov cr.itir=r18
|
||||
mov cr.ifa=r13
|
||||
mov r20=IA64_TR_CURRENT_STACK
|
||||
;;
|
||||
itr.d dtr[r20]=r21
|
||||
;;
|
||||
srlz.d
|
||||
|
||||
br.sptk b0
|
||||
|
||||
|
@ -56,8 +56,9 @@ static struct page *page_isolate[MAX_PAGE_ISOLATE];
|
||||
static int num_page_isolate = 0;
|
||||
|
||||
typedef enum {
|
||||
ISOLATE_NG = 0,
|
||||
ISOLATE_OK = 1
|
||||
ISOLATE_NG,
|
||||
ISOLATE_OK,
|
||||
ISOLATE_NONE
|
||||
} isolate_status_t;
|
||||
|
||||
/*
|
||||
@ -74,7 +75,7 @@ static struct {
|
||||
* @paddr: poisoned memory location
|
||||
*
|
||||
* Return value:
|
||||
* ISOLATE_OK / ISOLATE_NG
|
||||
* one of isolate_status_t, ISOLATE_OK/NG/NONE.
|
||||
*/
|
||||
|
||||
static isolate_status_t
|
||||
@ -85,7 +86,10 @@ mca_page_isolate(unsigned long paddr)
|
||||
|
||||
/* whether physical address is valid or not */
|
||||
if (!ia64_phys_addr_valid(paddr))
|
||||
return ISOLATE_NG;
|
||||
return ISOLATE_NONE;
|
||||
|
||||
if (!pfn_valid(paddr))
|
||||
return ISOLATE_NONE;
|
||||
|
||||
/* convert physical address to physical page number */
|
||||
p = pfn_to_page(paddr>>PAGE_SHIFT);
|
||||
@ -122,10 +126,15 @@ mca_handler_bh(unsigned long paddr)
|
||||
current->pid, current->comm);
|
||||
|
||||
spin_lock(&mca_bh_lock);
|
||||
if (mca_page_isolate(paddr) == ISOLATE_OK) {
|
||||
switch (mca_page_isolate(paddr)) {
|
||||
case ISOLATE_OK:
|
||||
printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr);
|
||||
} else {
|
||||
break;
|
||||
case ISOLATE_NG:
|
||||
printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
spin_unlock(&mca_bh_lock);
|
||||
|
||||
|
@ -80,7 +80,12 @@ struct ia64_sal_os_state {
|
||||
u64 sal_ra; /* Return address in SAL, physical */
|
||||
u64 sal_gp; /* GP of the SAL - physical */
|
||||
pal_min_state_area_t *pal_min_state; /* from R17. physical in asm, virtual in C */
|
||||
/* Previous values of IA64_KR(CURRENT) and IA64_KR(CURRENT_STACK).
|
||||
* Note: if the MCA/INIT recovery code wants to resume to a new context
|
||||
* then it must change these values to reflect the new kernel stack.
|
||||
*/
|
||||
u64 prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */
|
||||
u64 prev_IA64_KR_CURRENT_STACK;
|
||||
struct task_struct *prev_task; /* previous task, NULL if it is not useful */
|
||||
/* Some interrupt registers are not saved in minstate, pt_regs or
|
||||
* switch_stack. Because MCA/INIT can occur when interrupts are
|
||||
|
Loading…
Reference in New Issue
Block a user