|
|
Author: dwmw2
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv25414
Modified Files:
kernel-2.6.spec linux-2.6-ps3-fix-slowdown-bug.patch
Added Files:
linux-2.6-ps3-read-cd.patch linux-2.6-ps3-smp-boot.patch
Log Message:
PS3 fixes
linux-2.6-ps3-read-cd.patch:
ps3_storage.c | 183 ++++++++++++++++++++++++++++++++++++----------------------
ps3_storage.h | 20 ++++--
2 files changed, 127 insertions(+), 76 deletions(-)
--- NEW FILE linux-2.6-ps3-read-cd.patch ---
---
drivers/block/ps3_storage.c | 183 +++++++++++++++++++++++++++-----------------
drivers/block/ps3_storage.h | 20 +++-
2 files changed, 127 insertions(+), 76 deletions(-)
--- ps3-linux-mokuno.orig/drivers/block/ps3_storage.c
+++ ps3-linux-mokuno/drivers/block/ps3_storage.c
@@ -92,6 +92,8 @@ static int ps3_stor_lv1_devnum ; /* numb
static LIST_HEAD(ps3_stor_host_list);
static DEFINE_SPINLOCK(ps3_stor_host_list_lock);
+static u64 ps3_stor_virtual_to_lpar(struct ps3_stor_dev_info *dev_info,
+ void *va);
/*
* fill buf with MODE SENSE page 8 (caching parameter)
@@ -396,55 +398,70 @@ static int issue_atapi_by_srb(struct ps3
const struct scsi_command_handler_info * handler_info;
unsigned char * cmnd = dev_info->srb->cmnd;
int bounce_len = 0;
- unsigned char * bounce_buf = NULL;
int error;
unsigned char keys[4];
handler_info = &(dev_info->handler_info[cmnd[0]]);
- /* alloc bounce buffer if needed */
- if (handler_info->buflen == USE_SRB_6) {
+ /* check buffer size */
+ switch (handler_info->buflen) {
+ case USE_SRB_6:
bounce_len = cmnd[4];
- } else if (handler_info->buflen == USE_SRB_10) {
- bounce_len = (cmnd[7] << 8) | cmnd[8];
- } else {
+ break;
+ case USE_SRB_10:
+ bounce_len = (cmnd[7] << 8) | cmnd[8];
+ break;
+ case USE_CDDA_FRAME_RAW:
+ bounce_len = ((cmnd[6] << 16) |
+ (cmnd[7] << 8) |
+ (cmnd[8] << 0)) * CD_FRAMESIZE_RAW;
+ break;
+ default:
bounce_len = handler_info->buflen;
}
- if (bounce_len)
- bounce_buf = kmalloc(bounce_len, GFP_NOIO);
-
+ if (dev_info->dedicated_bounce_size < bounce_len ) {
+ static int printed;
+ if (!printed++)
+ printk(KERN_ERR "%s: data size too large %#x<%#x\n",
+ __FUNCTION__,
+ dev_info->dedicated_bounce_size,
+ bounce_len);
+ dev_info->srb->result = DID_ERROR << 16;
+ memset(dev_info->srb->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ dev_info->srb->sense_buffer[0] = 0x70;
+ dev_info->srb->sense_buffer[2] = ILLEGAL_REQUEST;
+ return -1;
+ }
memset(&atapi_cmnd, 0, sizeof(struct lv1_atapi_cmnd_block));
memcpy(&(atapi_cmnd.pkt), cmnd, 12);
atapi_cmnd.pktlen = 12;
atapi_cmnd.proto = handler_info->proto;
- if (atapi_cmnd.proto == PIO_DATA_OUT_PROTO) {
- atapi_cmnd.in_out = DIR_MEMORY_TO_ATAPI;
- fetch_to_dev_buffer(dev_info->srb, bounce_buf, bounce_len);
- } else
- atapi_cmnd.in_out = DIR_ATAPI_TO_MEMORY;
+ if (handler_info->in_out != DIR_NA)
+ atapi_cmnd.in_out = handler_info->in_out;
+
+ if (atapi_cmnd.in_out == DIR_WRITE)
+ fetch_to_dev_buffer(dev_info->srb, dev_info->bounce_buf,
bounce_len);
atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */
atapi_cmnd.blocks = atapi_cmnd.arglen = bounce_len;
- atapi_cmnd.buffer = ps3_mm_phys_to_lpar(__pa(bounce_buf)); /* no need
special convert */
+ atapi_cmnd.buffer = ps3_stor_virtual_to_lpar(dev_info,
dev_info->bounce_buf);
/* issue command */
init_completion(&(dev_info->irq_done));
error = lv1_storage_send_device_command(lv1_dev_info->repo.did.dev_id,
LV1_STORAGE_SEND_ATAPI_COMMAND,
-
ps3_mm_phys_to_lpar(__pa(&atapi_cmnd)), /* no need special convert */
+
ps3_mm_phys_to_lpar(__pa(&atapi_cmnd)),
sizeof(struct
lv1_atapi_cmnd_block),
atapi_cmnd.buffer,
- atapi_cmnd.blocks,
+ atapi_cmnd.arglen,
&lv1_dev_info->current_tag);
if (error) {
printk(KERN_ERR "%s: send_device failed lv1dev=%u ret=%d\n",
__FUNCTION__, lv1_dev_info->repo.did.dev_id, error);
dev_info->srb->result = DID_ERROR << 16; /* FIXME: is better
other error code ? */
- if (bounce_buf)
- kfree(bounce_buf);
return -1;
}
@@ -454,18 +471,12 @@ static int issue_atapi_by_srb(struct ps3
/* check error */
if (!dev_info->lv1_status) {
/* OK, completed */
- if (atapi_cmnd.proto == PIO_DATA_IN_PROTO)
- fill_from_dev_buffer(dev_info->srb, bounce_buf,
bounce_len);
+ if (atapi_cmnd.in_out == DIR_READ)
+ fill_from_dev_buffer(dev_info->srb,
dev_info->bounce_buf, bounce_len);
dev_info->srb->result = DID_OK << 16;
- if (bounce_buf)
- kfree(bounce_buf);
return 0;
}
- if (bounce_buf) {
- kfree(bounce_buf);
- bounce_buf = NULL;
- }
/* error */
if (!auto_sense) {
dev_info->srb->result = (DID_ERROR << 16) | (CHECK_CONDITION <<
1);
@@ -484,16 +495,15 @@ static int issue_atapi_by_srb(struct ps3
dev_info->srb->result = SAM_STAT_CHECK_CONDITION;
} else {
/* do auto sense by our selves*/
- bounce_buf = kzalloc(18, GFP_NOIO);
memset(&atapi_cmnd, 0, sizeof(struct lv1_atapi_cmnd_block));
atapi_cmnd.pkt[0] = REQUEST_SENSE;
atapi_cmnd.pkt[4] = 18;
atapi_cmnd.pktlen = 12;
atapi_cmnd.arglen = atapi_cmnd.blocks = atapi_cmnd.pkt[4];
atapi_cmnd.block_size = 1;
- atapi_cmnd.proto = PIO_DATA_IN_PROTO;
- atapi_cmnd.in_out = DIR_ATAPI_TO_MEMORY;
- atapi_cmnd.buffer = ps3_mm_phys_to_lpar(__pa(bounce_buf));
+ atapi_cmnd.proto = DMA_PROTO;
+ atapi_cmnd.in_out = DIR_READ;
+ atapi_cmnd.buffer =
ps3_stor_virtual_to_lpar(dev_info,dev_info->bounce_buf);
/* issue REQUEST_SENSE command */
init_completion(&(dev_info->irq_done));
@@ -502,7 +512,7 @@ static int issue_atapi_by_srb(struct ps3
ps3_mm_phys_to_lpar(__pa(&atapi_cmnd)),
sizeof(struct
lv1_atapi_cmnd_block),
atapi_cmnd.buffer,
- atapi_cmnd.blocks,
+ atapi_cmnd.arglen,
&lv1_dev_info->current_tag);
if (error) {
printk(KERN_ERR "%s: send_device for request sense
failed lv1dev=%u ret=%d\n", __FUNCTION__,
@@ -522,9 +532,8 @@ static int issue_atapi_by_srb(struct ps3
keys[0], keys[1], keys[2]);
}
- memcpy(dev_info->srb->sense_buffer, bounce_buf,
min((int)atapi_cmnd.pkt[4], SCSI_SENSE_BUFFERSIZE));
- if (bounce_buf)
- kfree(bounce_buf);
+ memcpy(dev_info->srb->sense_buffer, dev_info->bounce_buf,
+ min((int)atapi_cmnd.pkt[4], SCSI_SENSE_BUFFERSIZE));
dev_info->srb->result = SAM_STAT_CHECK_CONDITION;
}
@@ -1997,48 +2006,84 @@ static int ps3_stor_wait_device_ready(vo
static const struct scsi_command_handler_info scsi_cmnd_info_table_hdd[256] =
{
- [INQUIRY] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_inquiry},
- [REQUEST_SENSE] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_request_sense},
- [TEST_UNIT_READY] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_just_ok},
- [READ_CAPACITY] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_read_capacity},
- [MODE_SENSE_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_mode_sense},
- [SYNCHRONIZE_CACHE] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_sync_cache},
- [READ_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_read},
- [READ_6] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_read},
- [WRITE_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_write},
- [WRITE_6] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_write}
+ [INQUIRY] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_inquiry},
+ [REQUEST_SENSE] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_request_sense},
+ [TEST_UNIT_READY] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_just_ok},
+ [READ_CAPACITY] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_read_capacity},
+ [MODE_SENSE_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_mode_sense},
+ [SYNCHRONIZE_CACHE] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_sync_cache},
+ [READ_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_read},
+ [READ_6] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_read},
+ [WRITE_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_write},
+ [WRITE_6] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_write}
};
static const struct scsi_command_handler_info scsi_cmnd_info_table_flash[256] =
{
- [INQUIRY] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_inquiry},
- [REQUEST_SENSE] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_request_sense},
- [TEST_UNIT_READY] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_just_ok},
- [READ_CAPACITY] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_read_capacity},
- [MODE_SENSE_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_mode_sense},
- [SYNCHRONIZE_CACHE] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_hdd_handle_sync_cache},
- [READ_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_read},
- [READ_6] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_read},
- [WRITE_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_handle_write_flash},
- [WRITE_6] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_handle_write_flash}
+ [INQUIRY] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_inquiry},
+ [REQUEST_SENSE] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_request_sense},
+ [TEST_UNIT_READY] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_just_ok},
+ [READ_CAPACITY] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_read_capacity},
+ [MODE_SENSE_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_mode_sense},
+ [SYNCHRONIZE_CACHE] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_hdd_handle_sync_cache},
+ [READ_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_read},
+ [READ_6] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_read},
+ [WRITE_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_handle_write_flash},
+ [WRITE_6] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_handle_write_flash}
};
static const struct scsi_command_handler_info scsi_cmnd_info_table_atapi[256] =
{
- [INQUIRY] = { USE_SRB_6, PIO_DATA_IN_PROTO,
ps3_stor_atapi_handle_simple},
- [REQUEST_SENSE] = { USE_SRB_6, PIO_DATA_IN_PROTO,
ps3_stor_atapi_handle_request_sense},
- [START_STOP] = { 0, NON_DATA_PROTO,
ps3_stor_atapi_handle_simple},
- [ALLOW_MEDIUM_REMOVAL] = { 0, NON_DATA_PROTO,
ps3_stor_atapi_handle_simple},
- [TEST_UNIT_READY] = { 0, NON_DATA_PROTO,
ps3_stor_atapi_handle_simple},
- [READ_CAPACITY] = { 8, PIO_DATA_IN_PROTO,
ps3_stor_atapi_handle_simple},
- [MODE_SENSE_10] = { USE_SRB_10, PIO_DATA_IN_PROTO,
ps3_stor_atapi_handle_simple},
- [READ_TOC] = { USE_SRB_10, PIO_DATA_IN_PROTO,
ps3_stor_atapi_handle_simple},
- [GPCMD_GET_CONFIGURATION] = { USE_SRB_10, PIO_DATA_IN_PROTO,
ps3_stor_atapi_handle_simple},
- [GPCMD_READ_DISC_INFO] = { USE_SRB_10, PIO_DATA_IN_PROTO,
ps3_stor_atapi_handle_simple},
- [READ_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_read},
- [READ_6] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_read},
- [WRITE_10] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_write},
- [WRITE_6] = { NOT_AVAIL, NOT_AVAIL,
ps3_stor_common_handle_write}
+ [INQUIRY] = {USE_SRB_6, PIO_DATA_IN_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_simple},
+ [REQUEST_SENSE] = {USE_SRB_6, PIO_DATA_IN_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_request_sense},
+ [START_STOP] = {0, NON_DATA_PROTO, DIR_NA,
+ ps3_stor_atapi_handle_simple},
+ [ALLOW_MEDIUM_REMOVAL] = {0, NON_DATA_PROTO, DIR_NA,
+ ps3_stor_atapi_handle_simple},
+ [TEST_UNIT_READY] = {0, NON_DATA_PROTO, DIR_NA,
+ ps3_stor_atapi_handle_simple},
+ [READ_CAPACITY] = {8, PIO_DATA_IN_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_simple},
+ [MODE_SENSE_10] = {USE_SRB_10, PIO_DATA_IN_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_simple},
+ [READ_TOC] = {USE_SRB_10, PIO_DATA_IN_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_simple},
+ [GPCMD_GET_CONFIGURATION] = {USE_SRB_10, PIO_DATA_IN_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_simple},
+ [GPCMD_READ_DISC_INFO] = {USE_SRB_10, PIO_DATA_IN_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_simple},
+ [READ_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_read},
+ [READ_6] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_read},
+ [WRITE_10] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_write},
+ [WRITE_6] = {NOT_AVAIL, NA_PROTO, DIR_NA,
+ ps3_stor_common_handle_write},
+ [GPCMD_READ_CD] = {USE_CDDA_FRAME_RAW, DMA_PROTO, DIR_READ,
+ ps3_stor_atapi_handle_simple}
};
--- ps3-linux-mokuno.orig/drivers/block/ps3_storage.h
+++ ps3-linux-mokuno/drivers/block/ps3_storage.h
@@ -47,14 +47,17 @@ struct lv1_atapi_cmnd_block {
};
enum lv1_atapi_proto {
+ NA_PROTO = -1,
NON_DATA_PROTO = 0,
PIO_DATA_IN_PROTO = 1,
- PIO_DATA_OUT_PROTO = 2
+ PIO_DATA_OUT_PROTO = 2,
+ DMA_PROTO = 3
};
enum lv1_atapi_in_out {
- DIR_MEMORY_TO_ATAPI = 0,
- DIR_ATAPI_TO_MEMORY = 1
+ DIR_NA = -1,
+ DIR_WRITE = 0, /* memory -> device */
+ DIR_READ = 1 /* device -> memory */
};
/*
@@ -65,16 +68,19 @@ struct ps3_stor_dev_info;
struct scsi_command_handler_info {
int buflen;
int proto;
+ int in_out;
int (*cmnd_handler)(struct ps3_stor_dev_info *, struct scsi_cmnd *);
};
/*
* to position parameter
*/
-
-#define NOT_AVAIL (-1)
-#define USE_SRB_10 (-2)
-#define USE_SRB_6 (-3)
+enum {
+ NOT_AVAIL = -1,
+ USE_SRB_10 = -2,
+ USE_SRB_6 = -3,
+ USE_CDDA_FRAME_RAW = -4
+};
/*
* for LV1 maintainance
*/
linux-2.6-ps3-smp-boot.patch:
head_64.S | 29 ++++++++++++++++++++++++++---
1 files changed, 26 insertions(+), 3 deletions(-)
--- NEW FILE linux-2.6-ps3-smp-boot.patch ---
--- linux-2.6.20.ppc64/arch/powerpc/kernel/head_64.S.orig 2007-04-16
14:40:03.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/kernel/head_64.S 2007-04-16
14:40:18.000000000 +0100
@@ -103,8 +103,8 @@ __secondary_hold_acknowledge:
. = 0x60
/*
- * The following code is used on pSeries to hold secondary processors
- * in a spin loop after they have been freed from OpenFirmware, but
+ * The following code is used to hold secondary processors
+ * in a spin loop after they have entered the kernel, but
* before the bulk of the kernel has been relocated. This code
* is relocated to physical address 0x60 before prom_init is run.
* All of it must fit below the first exception vector at 0x100.
@@ -1689,9 +1689,32 @@ _GLOBAL(__start_initialization_multiplat
2:
/* Switch off MMU if not already */
- LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
+ LOAD_REG_IMMEDIATE(r4, __mmu_off_return - KERNELBASE)
add r4,r4,r30
bl .__mmu_off
+__mmu_off_return:
+
+ /* Test if this is a secondary cpu and if so send it off to
+ * __secondary_hold with a thread number in r3. Secondary processors
+ * call _start with regs r3,r4,r5 zeroed.
+ * Pass cpu number in r6???
+ */
+ or. r3, r31, r30
+ bne 1f
+ li r3, 1
+ b .__secondary_hold
+1:
+
+ /* The primary cpu waits here for all the expected secondary cpus to
+ * enter the kernel, after which time it is safe to reclaim the
+ * memory use by the bootwrapper.
+ * How to know what to wait for???
+ * !!! need to use the kexec entry mechanism here!!!!
+ */
+1: LOAD_REG_IMMEDIATE(r4, __secondary_hold_acknowledge)
+ cmpwi r4, 0
+ beq 1b
+ mr r3, r30
b .__after_prom_start
_STATIC(__boot_from_prom)
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.3071
retrieving revision 1.3072
diff -u -r1.3071 -r1.3072
--- kernel-2.6.spec 16 Apr 2007 02:44:55 -0000 1.3071
+++ kernel-2.6.spec 16 Apr 2007 14:16:39 -0000 1.3072
@@ -437,6 +437,9 @@
Patch354: linux-2.6-ps3-device-init.patch
Patch355: linux-2.6-ps3-fix-slowdown-bug.patch
Patch356: linux-2.6-ps3-sound.patch
+Patch357: linux-2.6-ps3-smp-boot.patch
+Patch358: linux-2.6-ps3-read-cd.patch
+
# And then some minor tweaks...
Patch360: linux-2.6-ps3-memory-probe.patch
Patch361: linux-2.6-ps3-legacy-ioport.patch
@@ -1057,6 +1060,8 @@
%patch354 -p1
%patch355 -p1
%patch356 -p1
+%patch357 -p1
+%patch358 -p1
%patch360 -p1
%patch361 -p1
@@ -2261,6 +2266,11 @@
# - tux.
%changelog
+* Mon Apr 16 2007 David Woodhouse <dwmw2@xxxxxxxxxx>
+- Correct fix for PS3 IRQ slowdown (HV bug)
+- Fix for CDDA reading on PS3
+- Fix handling of secondary PPU on PS3 boot
+
* Sun Apr 15 2007 Dave Jones <davej@xxxxxxxxxx>
- 2.6.21-rc7
linux-2.6-ps3-fix-slowdown-bug.patch:
irq.c | 11 +++++++++++
1 files changed, 11 insertions(+)
Index: linux-2.6-ps3-fix-slowdown-bug.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-ps3-fix-slowdown-bug.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- linux-2.6-ps3-fix-slowdown-bug.patch 30 Mar 2007 20:10:34 -0000
1.1
+++ linux-2.6-ps3-fix-slowdown-bug.patch 16 Apr 2007 14:16:39 -0000
1.2
@@ -1,65 +1,39 @@
-From: Takao Shinohara
+From: Takao Shinohara <shin@xxxxxxxxxxxxx>
-Change the PS3 interrupt handler from handle_fasteoi_irq to handle_level_irq.
+The PS3 HV will deliver soft-disabled interrupts at the next HV call or
+interrupt. Add an HV call to local_irq_restore() to force the timely delivery
+of any pending interrupts.
-WIP fix for PS3 slowdown bug http://bugzilla.kernel.org/show_bug.cgi?id=8260.
-
-This solves disk and sound slowness issue. But gelic network is still slow,
-it may have another problem. We did not check SPU slowdown was solved or not.
-
-The main reason why the slow down was caused is that it seems lv1 requires
-interrupts are masked just after entering guest os interrupt handler.
-The 2.6.16 interrupt handler does in that way.
-
-
-From: Takao Shinohara
-CC: MOKUNO Masakazu <mokuno@xxxxxxxxxxxxx>
+From: Takao Shinohara <shin@xxxxxxxxxxxxx>
Signed-off-by: Geoff Levand <geoffrey.levand@xxxxxxxxxxx>
-
---
- arch/powerpc/platforms/ps3/interrupt.c | 14 ++++----------
- 1 file changed, 4 insertions(+), 10 deletions(-)
+ arch/powerpc/kernel/irq.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
---- ps3-linux-dev.orig/arch/powerpc/platforms/ps3/interrupt.c
-+++ ps3-linux-dev/arch/powerpc/platforms/ps3/interrupt.c
-@@ -466,7 +466,7 @@ static void __attribute__ ((unused)) _du
- static void dump_bmp(struct ps3_private* pd) {};
- #endif /* defined(DEBUG) */
-
--static void ps3_chip_mask(unsigned int virq)
-+static void ps3_chip_mask_ack(unsigned int virq)
- {
- struct ps3_private *pd = get_irq_chip_data(virq);
- u64 bit = 0x8000000000000000UL >> virq;
-@@ -511,20 +511,14 @@ static void ps3_chip_unmask(unsigned int
- : "cc" );
-
- lv1_did_update_interrupt_mask(pd->node, pd->cpu);
-- local_irq_restore(flags);
--}
--
--static void ps3_chip_eoi(unsigned int virq)
--{
-- const struct ps3_private *pd = get_irq_chip_data(virq);
- lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
-+ local_irq_restore(flags);
- }
-
- static struct irq_chip irq_chip = {
- .typename = "ps3",
-- .mask = ps3_chip_mask,
-+ .mask_ack = ps3_chip_mask_ack,
- .unmask = ps3_chip_unmask,
-- .eoi = ps3_chip_eoi,
- };
-
- static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
-@@ -538,7 +532,7 @@ static int ps3_host_map(struct irq_host
- pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
- virq);
-
-- set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
-+ set_irq_chip_and_handler(virq, &irq_chip, handle_level_irq);
-
- return 0;
+--- ps3-linux-dev.orig/arch/powerpc/kernel/irq.c
++++ ps3-linux-dev/arch/powerpc/kernel/irq.c
+@@ -67,6 +67,7 @@
+ #ifdef CONFIG_PPC64
+ #include <asm/paca.h>
+ #include <asm/firmware.h>
++#include <asm/lv1call.h>
+ #endif
+
+ int __irq_offset_value;
+@@ -162,6 +163,16 @@ void local_irq_restore(unsigned long en)
+ local_paca->hard_enabled = en;
+ if ((int)mfspr(SPRN_DEC) < 0)
+ mtspr(SPRN_DEC, 1);
++
++ /*
++ * Force the delivery of pending soft-disabled interrupts on PS3.
++ * Any HV call will have this side effect.
++ */
++ if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
++ u64 tmp;
++ lv1_get_version_info(&tmp);
++ }
++
+ hard_irq_enable();
}
+ #endif /* CONFIG_PPC64 */
--
fedora-cvs-commits mailing list
fedora-cvs-commits@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/fedora-cvs-commits
|
|