Loading arch/ia64/hp/sim/simscsi.c +23 −6 Original line number Diff line number Diff line Loading @@ -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 *)) { Loading @@ -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"); Loading @@ -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 */ Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading arch/ia64/kernel/mca_asm.S +85 −11 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 ;; Loading @@ -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////////////////////////////////////////////////////////////////////// Loading Loading @@ -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 ;; Loading @@ -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 Loading arch/ia64/kernel/mca_drv.c +15 −6 Original line number Diff line number Diff line Loading @@ -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; /* Loading @@ -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 Loading @@ -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); Loading Loading @@ -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); Loading include/asm-ia64/mca.h +5 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
arch/ia64/hp/sim/simscsi.c +23 −6 Original line number Diff line number Diff line Loading @@ -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 *)) { Loading @@ -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"); Loading @@ -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 */ Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading
arch/ia64/kernel/mca_asm.S +85 −11 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 ;; Loading @@ -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////////////////////////////////////////////////////////////////////// Loading Loading @@ -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 ;; Loading @@ -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 Loading
arch/ia64/kernel/mca_drv.c +15 −6 Original line number Diff line number Diff line Loading @@ -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; /* Loading @@ -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 Loading @@ -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); Loading Loading @@ -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); Loading
include/asm-ia64/mca.h +5 −0 Original line number Diff line number Diff line Loading @@ -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