From: Greg Kroah-Hartman Date: Sun, 10 May 2015 12:32:09 +0000 (+0200) Subject: 4.0-stable patches X-Git-Tag: v3.19.8~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=273b002621aea278ae1175cf77be03e10050302f;p=thirdparty%2Fkernel%2Fstable-queue.git 4.0-stable patches added patches: 3w-9xxx-fix-command-completion-race.patch 3w-sas-fix-command-completion-race.patch 3w-xxxx-fix-command-completion-race.patch drm-radeon-add-si-dpm-quirk-for-sapphire-r9-270-dual-x-2g-gddr5.patch drm-radeon-adjust-pll-when-audio-is-not-enabled.patch drm-radeon-audio-don-t-enable-packets-until-the-end.patch drm-radeon-check-new-address-before-removing-old-one.patch drm-radeon-drop-dce6_dp_enable.patch drm-radeon-fix-lockup-when-bos-aren-t-part-of-the-vm-on-release.patch drm-radeon-fix-ordering-of-avi-packet-setup.patch drm-radeon-only-enable-audio-streams-if-the-monitor-supports-it.patch drm-radeon-only-mark-audio-as-connected-if-the-monitor-supports-it-v3.patch drm-radeon-reset-bos-address-after-clearing-it.patch drm-radeon-use-drm_calloc_ab-for-cs-relocs.patch hfsplus-don-t-store-special-osx-xattr-prefix-on-disk.patch scsi-add-1024-max-sectors-black-list-flag.patch --- diff --git a/queue-4.0/3w-9xxx-fix-command-completion-race.patch b/queue-4.0/3w-9xxx-fix-command-completion-race.patch new file mode 100644 index 00000000000..597b052489b --- /dev/null +++ b/queue-4.0/3w-9xxx-fix-command-completion-race.patch @@ -0,0 +1,157 @@ +From 118c855b5623f3e2e6204f02623d88c09e0c34de Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Thu, 23 Apr 2015 09:48:51 +0200 +Subject: 3w-9xxx: fix command completion race + +From: Christoph Hellwig + +commit 118c855b5623f3e2e6204f02623d88c09e0c34de upstream. + +The 3w-9xxx driver needs to tear down the dma mappings before returning +the command to the midlayer, as there is no guarantee the sglist and +count are valid after that point. Also remove the dma mapping helpers +which have another inherent race due to the request_id index. + +Signed-off-by: Christoph Hellwig +Acked-by: Adam Radford +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/3w-9xxx.c | 57 +++++++++++-------------------------------------- + drivers/scsi/3w-9xxx.h | 5 ---- + 2 files changed, 13 insertions(+), 49 deletions(-) + +--- a/drivers/scsi/3w-9xxx.c ++++ b/drivers/scsi/3w-9xxx.c +@@ -149,7 +149,6 @@ static int twa_reset_sequence(TW_Device_ + static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg); + static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id); + static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code); +-static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id); + + /* Functions */ + +@@ -1340,11 +1339,11 @@ static irqreturn_t twa_interrupt(int irq + } + + /* Now complete the io */ ++ scsi_dma_unmap(cmd); ++ cmd->scsi_done(cmd); + tw_dev->state[request_id] = TW_S_COMPLETED; + twa_free_request_id(tw_dev, request_id); + tw_dev->posted_request_count--; +- tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); +- twa_unmap_scsi_data(tw_dev, request_id); + } + + /* Check for valid status after each drain */ +@@ -1402,26 +1401,6 @@ static void twa_load_sgl(TW_Device_Exten + } + } /* End twa_load_sgl() */ + +-/* This function will perform a pci-dma mapping for a scatter gather list */ +-static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id) +-{ +- int use_sg; +- struct scsi_cmnd *cmd = tw_dev->srb[request_id]; +- +- use_sg = scsi_dma_map(cmd); +- if (!use_sg) +- return 0; +- else if (use_sg < 0) { +- TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list"); +- return 0; +- } +- +- cmd->SCp.phase = TW_PHASE_SGLIST; +- cmd->SCp.have_data_in = use_sg; +- +- return use_sg; +-} /* End twa_map_scsi_sg_data() */ +- + /* This function will poll for a response interrupt of a request */ + static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds) + { +@@ -1600,9 +1579,11 @@ static int twa_reset_device_extension(TW + (tw_dev->state[i] != TW_S_INITIAL) && + (tw_dev->state[i] != TW_S_COMPLETED)) { + if (tw_dev->srb[i]) { +- tw_dev->srb[i]->result = (DID_RESET << 16); +- tw_dev->srb[i]->scsi_done(tw_dev->srb[i]); +- twa_unmap_scsi_data(tw_dev, i); ++ struct scsi_cmnd *cmd = tw_dev->srb[i]; ++ ++ cmd->result = (DID_RESET << 16); ++ scsi_dma_unmap(cmd); ++ cmd->scsi_done(cmd); + } + } + } +@@ -1781,21 +1762,18 @@ static int twa_scsi_queue_lck(struct scs + /* Save the scsi command for use by the ISR */ + tw_dev->srb[request_id] = SCpnt; + +- /* Initialize phase to zero */ +- SCpnt->SCp.phase = TW_PHASE_INITIAL; +- + retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL); + switch (retval) { + case SCSI_MLQUEUE_HOST_BUSY: ++ scsi_dma_unmap(SCpnt); + twa_free_request_id(tw_dev, request_id); +- twa_unmap_scsi_data(tw_dev, request_id); + break; + case 1: +- tw_dev->state[request_id] = TW_S_COMPLETED; +- twa_free_request_id(tw_dev, request_id); +- twa_unmap_scsi_data(tw_dev, request_id); + SCpnt->result = (DID_ERROR << 16); ++ scsi_dma_unmap(SCpnt); + done(SCpnt); ++ tw_dev->state[request_id] = TW_S_COMPLETED; ++ twa_free_request_id(tw_dev, request_id); + retval = 0; + } + out: +@@ -1863,8 +1841,8 @@ static int twa_scsiop_execute_scsi(TW_De + command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); + command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); + } else { +- sg_count = twa_map_scsi_sg_data(tw_dev, request_id); +- if (sg_count == 0) ++ sg_count = scsi_dma_map(srb); ++ if (sg_count < 0) + goto out; + + scsi_for_each_sg(srb, sg, sg_count, i) { +@@ -1979,15 +1957,6 @@ static char *twa_string_lookup(twa_messa + return(table[index].text); + } /* End twa_string_lookup() */ + +-/* This function will perform a pci-dma unmap */ +-static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id) +-{ +- struct scsi_cmnd *cmd = tw_dev->srb[request_id]; +- +- if (cmd->SCp.phase == TW_PHASE_SGLIST) +- scsi_dma_unmap(cmd); +-} /* End twa_unmap_scsi_data() */ +- + /* This function gets called when a disk is coming on-line */ + static int twa_slave_configure(struct scsi_device *sdev) + { +--- a/drivers/scsi/3w-9xxx.h ++++ b/drivers/scsi/3w-9xxx.h +@@ -324,11 +324,6 @@ static twa_message_type twa_error_table[ + #define TW_CURRENT_DRIVER_BUILD 0 + #define TW_CURRENT_DRIVER_BRANCH 0 + +-/* Phase defines */ +-#define TW_PHASE_INITIAL 0 +-#define TW_PHASE_SINGLE 1 +-#define TW_PHASE_SGLIST 2 +- + /* Misc defines */ + #define TW_9550SX_DRAIN_COMPLETED 0xFFFF + #define TW_SECTOR_SIZE 512 diff --git a/queue-4.0/3w-sas-fix-command-completion-race.patch b/queue-4.0/3w-sas-fix-command-completion-race.patch new file mode 100644 index 00000000000..de31546389a --- /dev/null +++ b/queue-4.0/3w-sas-fix-command-completion-race.patch @@ -0,0 +1,136 @@ +From 579d69bc1fd56d5af5761969aa529d1d1c188300 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Thu, 23 Apr 2015 09:48:49 +0200 +Subject: 3w-sas: fix command completion race + +From: Christoph Hellwig + +commit 579d69bc1fd56d5af5761969aa529d1d1c188300 upstream. + +The 3w-sas driver needs to tear down the dma mappings before returning +the command to the midlayer, as there is no guarantee the sglist and +count are valid after that point. Also remove the dma mapping helpers +which have another inherent race due to the request_id index. + +Signed-off-by: Christoph Hellwig +Reported-by: Torsten Luettgert +Tested-by: Bernd Kardatzki +Acked-by: Adam Radford +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/3w-sas.c | 50 ++++++++++---------------------------------------- + drivers/scsi/3w-sas.h | 4 ---- + 2 files changed, 10 insertions(+), 44 deletions(-) + +--- a/drivers/scsi/3w-sas.c ++++ b/drivers/scsi/3w-sas.c +@@ -290,26 +290,6 @@ static int twl_post_command_packet(TW_De + return 0; + } /* End twl_post_command_packet() */ + +-/* This function will perform a pci-dma mapping for a scatter gather list */ +-static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id) +-{ +- int use_sg; +- struct scsi_cmnd *cmd = tw_dev->srb[request_id]; +- +- use_sg = scsi_dma_map(cmd); +- if (!use_sg) +- return 0; +- else if (use_sg < 0) { +- TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list"); +- return 0; +- } +- +- cmd->SCp.phase = TW_PHASE_SGLIST; +- cmd->SCp.have_data_in = use_sg; +- +- return use_sg; +-} /* End twl_map_scsi_sg_data() */ +- + /* This function hands scsi cdb's to the firmware */ + static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg) + { +@@ -357,8 +337,8 @@ static int twl_scsiop_execute_scsi(TW_De + if (!sglistarg) { + /* Map sglist from scsi layer to cmd packet */ + if (scsi_sg_count(srb)) { +- sg_count = twl_map_scsi_sg_data(tw_dev, request_id); +- if (sg_count == 0) ++ sg_count = scsi_dma_map(srb); ++ if (sg_count <= 0) + goto out; + + scsi_for_each_sg(srb, sg, sg_count, i) { +@@ -1102,15 +1082,6 @@ out: + return retval; + } /* End twl_initialize_device_extension() */ + +-/* This function will perform a pci-dma unmap */ +-static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id) +-{ +- struct scsi_cmnd *cmd = tw_dev->srb[request_id]; +- +- if (cmd->SCp.phase == TW_PHASE_SGLIST) +- scsi_dma_unmap(cmd); +-} /* End twl_unmap_scsi_data() */ +- + /* This function will handle attention interrupts */ + static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev) + { +@@ -1251,11 +1222,11 @@ static irqreturn_t twl_interrupt(int irq + } + + /* Now complete the io */ ++ scsi_dma_unmap(cmd); ++ cmd->scsi_done(cmd); + tw_dev->state[request_id] = TW_S_COMPLETED; + twl_free_request_id(tw_dev, request_id); + tw_dev->posted_request_count--; +- tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); +- twl_unmap_scsi_data(tw_dev, request_id); + } + + /* Check for another response interrupt */ +@@ -1400,10 +1371,12 @@ static int twl_reset_device_extension(TW + if ((tw_dev->state[i] != TW_S_FINISHED) && + (tw_dev->state[i] != TW_S_INITIAL) && + (tw_dev->state[i] != TW_S_COMPLETED)) { +- if (tw_dev->srb[i]) { +- tw_dev->srb[i]->result = (DID_RESET << 16); +- tw_dev->srb[i]->scsi_done(tw_dev->srb[i]); +- twl_unmap_scsi_data(tw_dev, i); ++ struct scsi_cmnd *cmd = tw_dev->srb[i]; ++ ++ if (cmd) { ++ cmd->result = (DID_RESET << 16); ++ scsi_dma_unmap(cmd); ++ cmd->scsi_done(cmd); + } + } + } +@@ -1507,9 +1480,6 @@ static int twl_scsi_queue_lck(struct scs + /* Save the scsi command for use by the ISR */ + tw_dev->srb[request_id] = SCpnt; + +- /* Initialize phase to zero */ +- SCpnt->SCp.phase = TW_PHASE_INITIAL; +- + retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL); + if (retval) { + tw_dev->state[request_id] = TW_S_COMPLETED; +--- a/drivers/scsi/3w-sas.h ++++ b/drivers/scsi/3w-sas.h +@@ -103,10 +103,6 @@ static char *twl_aen_severity_table[] = + #define TW_CURRENT_DRIVER_BUILD 0 + #define TW_CURRENT_DRIVER_BRANCH 0 + +-/* Phase defines */ +-#define TW_PHASE_INITIAL 0 +-#define TW_PHASE_SGLIST 2 +- + /* Misc defines */ + #define TW_SECTOR_SIZE 512 + #define TW_MAX_UNITS 32 diff --git a/queue-4.0/3w-xxxx-fix-command-completion-race.patch b/queue-4.0/3w-xxxx-fix-command-completion-race.patch new file mode 100644 index 00000000000..f4b4916d9be --- /dev/null +++ b/queue-4.0/3w-xxxx-fix-command-completion-race.patch @@ -0,0 +1,120 @@ +From 9cd9554615cba14f0877cc9972a6537ad2bdde61 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Thu, 23 Apr 2015 09:48:50 +0200 +Subject: 3w-xxxx: fix command completion race + +From: Christoph Hellwig + +commit 9cd9554615cba14f0877cc9972a6537ad2bdde61 upstream. + +The 3w-xxxx driver needs to tear down the dma mappings before returning +the command to the midlayer, as there is no guarantee the sglist and +count are valid after that point. Also remove the dma mapping helpers +which have another inherent race due to the request_id index. + +Signed-off-by: Christoph Hellwig +Acked-by: Adam Radford +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/3w-xxxx.c | 42 ++++++------------------------------------ + drivers/scsi/3w-xxxx.h | 5 ----- + 2 files changed, 6 insertions(+), 41 deletions(-) + +--- a/drivers/scsi/3w-xxxx.c ++++ b/drivers/scsi/3w-xxxx.c +@@ -1271,32 +1271,6 @@ static int tw_initialize_device_extensio + return 0; + } /* End tw_initialize_device_extension() */ + +-static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) +-{ +- int use_sg; +- +- dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n"); +- +- use_sg = scsi_dma_map(cmd); +- if (use_sg < 0) { +- printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n"); +- return 0; +- } +- +- cmd->SCp.phase = TW_PHASE_SGLIST; +- cmd->SCp.have_data_in = use_sg; +- +- return use_sg; +-} /* End tw_map_scsi_sg_data() */ +- +-static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) +-{ +- dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n"); +- +- if (cmd->SCp.phase == TW_PHASE_SGLIST) +- scsi_dma_unmap(cmd); +-} /* End tw_unmap_scsi_data() */ +- + /* This function will reset a device extension */ + static int tw_reset_device_extension(TW_Device_Extension *tw_dev) + { +@@ -1319,8 +1293,8 @@ static int tw_reset_device_extension(TW_ + srb = tw_dev->srb[i]; + if (srb != NULL) { + srb->result = (DID_RESET << 16); +- tw_dev->srb[i]->scsi_done(tw_dev->srb[i]); +- tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]); ++ scsi_dma_unmap(srb); ++ srb->scsi_done(srb); + } + } + } +@@ -1767,8 +1741,8 @@ static int tw_scsiop_read_write(TW_Devic + command_packet->byte8.io.lba = lba; + command_packet->byte6.block_count = num_sectors; + +- use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]); +- if (!use_sg) ++ use_sg = scsi_dma_map(srb); ++ if (use_sg <= 0) + return 1; + + scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) { +@@ -1955,9 +1929,6 @@ static int tw_scsi_queue_lck(struct scsi + /* Save the scsi command for use by the ISR */ + tw_dev->srb[request_id] = SCpnt; + +- /* Initialize phase to zero */ +- SCpnt->SCp.phase = TW_PHASE_INITIAL; +- + switch (*command) { + case READ_10: + case READ_6: +@@ -2185,12 +2156,11 @@ static irqreturn_t tw_interrupt(int irq, + + /* Now complete the io */ + if ((error != TW_ISR_DONT_COMPLETE)) { ++ scsi_dma_unmap(tw_dev->srb[request_id]); ++ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + tw_dev->state[request_id] = TW_S_COMPLETED; + tw_state_request_finish(tw_dev, request_id); + tw_dev->posted_request_count--; +- tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); +- +- tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]); + } + } + +--- a/drivers/scsi/3w-xxxx.h ++++ b/drivers/scsi/3w-xxxx.h +@@ -195,11 +195,6 @@ static unsigned char tw_sense_table[][4] + #define TW_AEN_SMART_FAIL 0x000F + #define TW_AEN_SBUF_FAIL 0x0024 + +-/* Phase defines */ +-#define TW_PHASE_INITIAL 0 +-#define TW_PHASE_SINGLE 1 +-#define TW_PHASE_SGLIST 2 +- + /* Misc defines */ + #define TW_ALIGNMENT_6000 64 /* 64 bytes */ + #define TW_ALIGNMENT_7000 4 /* 4 bytes */ diff --git a/queue-4.0/drm-radeon-add-si-dpm-quirk-for-sapphire-r9-270-dual-x-2g-gddr5.patch b/queue-4.0/drm-radeon-add-si-dpm-quirk-for-sapphire-r9-270-dual-x-2g-gddr5.patch new file mode 100644 index 00000000000..3b21d5bad64 --- /dev/null +++ b/queue-4.0/drm-radeon-add-si-dpm-quirk-for-sapphire-r9-270-dual-x-2g-gddr5.patch @@ -0,0 +1,31 @@ +From cd17e02ff4db58ec32d35cf331c705d295779930 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 27 Apr 2015 09:51:43 -0400 +Subject: drm/radeon: add SI DPM quirk for Sapphire R9 270 Dual-X 2G GDDR5 + +From: Alex Deucher + +commit cd17e02ff4db58ec32d35cf331c705d295779930 upstream. + +Seems to have problems with high mclks. + +bug: +https://bugs.freedesktop.org/show_bug.cgi?id=76490 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/si_dpm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -2924,6 +2924,7 @@ struct si_dpm_quirk { + static struct si_dpm_quirk si_dpm_quirk_list[] = { + /* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ + { PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, ++ { PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 }, + { 0, 0, 0, 0 }, + }; + diff --git a/queue-4.0/drm-radeon-adjust-pll-when-audio-is-not-enabled.patch b/queue-4.0/drm-radeon-adjust-pll-when-audio-is-not-enabled.patch new file mode 100644 index 00000000000..40d11e83fb4 --- /dev/null +++ b/queue-4.0/drm-radeon-adjust-pll-when-audio-is-not-enabled.patch @@ -0,0 +1,36 @@ +From 7fe04d6fa824ccea704535a597dc417c8687f990 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Sun, 19 Apr 2015 12:01:00 -0400 +Subject: drm/radeon: adjust pll when audio is not enabled + +From: Alex Deucher + +commit 7fe04d6fa824ccea704535a597dc417c8687f990 upstream. + +Fixes display problems with some monitors when audio +is not enabled. + +Bugs: +https://bugs.freedesktop.org/show_bug.cgi?id=89505 +https://bugzilla.kernel.org/show_bug.cgi?id=94171 +Plus several reports on IRC. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -580,6 +580,9 @@ static u32 atombios_adjust_pll(struct dr + else + radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; + ++ /* if there is no audio, set MINM_OVER_MAXP */ ++ if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) ++ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; + if (rdev->family < CHIP_RV770) + radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; + /* use frac fb div on APUs */ diff --git a/queue-4.0/drm-radeon-audio-don-t-enable-packets-until-the-end.patch b/queue-4.0/drm-radeon-audio-don-t-enable-packets-until-the-end.patch new file mode 100644 index 00000000000..e4ce3854fef --- /dev/null +++ b/queue-4.0/drm-radeon-audio-don-t-enable-packets-until-the-end.patch @@ -0,0 +1,91 @@ +From 362ff251390f3d1f8fe94666f4fc4e5876381114 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 31 Mar 2015 11:43:12 -0400 +Subject: drm/radeon/audio: don't enable packets until the end + +From: Alex Deucher + +commit 362ff251390f3d1f8fe94666f4fc4e5876381114 upstream. + +Don't enable the audio and avi infoframes and audio stream +until all the state is set up. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/evergreen_hdmi.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c ++++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c +@@ -222,10 +222,6 @@ void evergreen_set_avi_packet(struct rad + WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset, + HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ + ~HDMI_AVI_INFO_LINE_MASK); +- +- WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, +- HDMI_AVI_INFO_SEND | /* enable AVI info frames */ +- HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ + } + + void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, +@@ -370,9 +366,13 @@ void dce4_set_audio_packet(struct drm_en + WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset, + AFMT_AUDIO_CHANNEL_ENABLE(0xff)); + ++ WREG32(HDMI_AUDIO_PACKET_CONTROL + offset, ++ HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */ ++ HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ ++ + /* allow 60958 channel status and send audio packets fields to be updated */ +- WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, +- AFMT_AUDIO_SAMPLE_SEND | AFMT_RESET_FIFO_WHEN_AUDIO_DIS | AFMT_60958_CS_UPDATE); ++ WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset, ++ AFMT_RESET_FIFO_WHEN_AUDIO_DIS | AFMT_60958_CS_UPDATE); + } + + +@@ -398,17 +398,16 @@ void evergreen_hdmi_enable(struct drm_en + return; + + if (enable) { +- WREG32(HDMI_INFOFRAME_CONTROL1 + dig->afmt->offset, +- HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */ +- +- WREG32(HDMI_AUDIO_PACKET_CONTROL + dig->afmt->offset, +- HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */ +- HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ +- + WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, ++ HDMI_AVI_INFO_SEND | /* enable AVI info frames */ ++ HDMI_AVI_INFO_CONT | /* required for audio info values to be updated */ + HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ + HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ ++ WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, ++ AFMT_AUDIO_SAMPLE_SEND); + } else { ++ WREG32_AND(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, ++ ~AFMT_AUDIO_SAMPLE_SEND); + WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, 0); + } + +@@ -434,6 +433,9 @@ void evergreen_dp_enable(struct drm_enco + struct radeon_connector_atom_dig *dig_connector; + uint32_t val; + ++ WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, ++ AFMT_AUDIO_SAMPLE_SEND); ++ + WREG32(EVERGREEN_DP_SEC_TIMESTAMP + dig->afmt->offset, + EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); + +@@ -457,6 +459,8 @@ void evergreen_dp_enable(struct drm_enco + EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ + } else { + WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset, 0); ++ WREG32_AND(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, ++ ~AFMT_AUDIO_SAMPLE_SEND); + } + + dig->afmt->enabled = enable; diff --git a/queue-4.0/drm-radeon-check-new-address-before-removing-old-one.patch b/queue-4.0/drm-radeon-check-new-address-before-removing-old-one.patch new file mode 100644 index 00000000000..cfe7d7028da --- /dev/null +++ b/queue-4.0/drm-radeon-check-new-address-before-removing-old-one.patch @@ -0,0 +1,70 @@ +From c29c0876ec05d51a93508a39b90b92c29ba6423d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Mon, 27 Apr 2015 17:04:36 +0200 +Subject: drm/radeon: check new address before removing old one +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Christian=20K=C3=B6nig?= + +commit c29c0876ec05d51a93508a39b90b92c29ba6423d upstream. + +Otherwise the change isn't atomic. + +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_vm.c | 31 +++++++++++++++++-------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_vm.c ++++ b/drivers/gpu/drm/radeon/radeon_vm.c +@@ -473,6 +473,23 @@ int radeon_vm_bo_set_addr(struct radeon_ + } + + mutex_lock(&vm->mutex); ++ soffset /= RADEON_GPU_PAGE_SIZE; ++ eoffset /= RADEON_GPU_PAGE_SIZE; ++ if (soffset || eoffset) { ++ struct interval_tree_node *it; ++ it = interval_tree_iter_first(&vm->va, soffset, eoffset - 1); ++ if (it && it != &bo_va->it) { ++ struct radeon_bo_va *tmp; ++ tmp = container_of(it, struct radeon_bo_va, it); ++ /* bo and tmp overlap, invalid offset */ ++ dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with " ++ "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo, ++ soffset, tmp->bo, tmp->it.start, tmp->it.last); ++ mutex_unlock(&vm->mutex); ++ return -EINVAL; ++ } ++ } ++ + if (bo_va->it.start || bo_va->it.last) { + if (bo_va->addr) { + /* add a clone of the bo_va to clear the old address */ +@@ -499,21 +516,7 @@ int radeon_vm_bo_set_addr(struct radeon_ + bo_va->it.last = 0; + } + +- soffset /= RADEON_GPU_PAGE_SIZE; +- eoffset /= RADEON_GPU_PAGE_SIZE; + if (soffset || eoffset) { +- struct interval_tree_node *it; +- it = interval_tree_iter_first(&vm->va, soffset, eoffset - 1); +- if (it) { +- struct radeon_bo_va *tmp; +- tmp = container_of(it, struct radeon_bo_va, it); +- /* bo and tmp overlap, invalid offset */ +- dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with " +- "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo, +- soffset, tmp->bo, tmp->it.start, tmp->it.last); +- mutex_unlock(&vm->mutex); +- return -EINVAL; +- } + bo_va->it.start = soffset; + bo_va->it.last = eoffset - 1; + interval_tree_insert(&bo_va->it, &vm->va); diff --git a/queue-4.0/drm-radeon-drop-dce6_dp_enable.patch b/queue-4.0/drm-radeon-drop-dce6_dp_enable.patch new file mode 100644 index 00000000000..e61fbeeb8c1 --- /dev/null +++ b/queue-4.0/drm-radeon-drop-dce6_dp_enable.patch @@ -0,0 +1,82 @@ +From 12428327bbd1180b5d8ef83fdf9482b878d0502a Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 31 Mar 2015 11:38:48 -0400 +Subject: drm/radeon: drop dce6_dp_enable + +From: Alex Deucher + +commit 12428327bbd1180b5d8ef83fdf9482b878d0502a upstream. + +It's mostly duplicated with evergreen_dp_enable. This +is a prerequisite for fix implemented in another patch. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/dce6_afmt.c | 25 ------------------------- + drivers/gpu/drm/radeon/evergreen_hdmi.c | 2 +- + drivers/gpu/drm/radeon/radeon_audio.c | 3 +-- + 3 files changed, 2 insertions(+), 28 deletions(-) + +--- a/drivers/gpu/drm/radeon/dce6_afmt.c ++++ b/drivers/gpu/drm/radeon/dce6_afmt.c +@@ -295,28 +295,3 @@ void dce6_dp_audio_set_dto(struct radeon + WREG32(DCCG_AUDIO_DTO1_MODULE, clock); + } + } +- +-void dce6_dp_enable(struct drm_encoder *encoder, bool enable) +-{ +- struct drm_device *dev = encoder->dev; +- struct radeon_device *rdev = dev->dev_private; +- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +- +- if (!dig || !dig->afmt) +- return; +- +- if (enable) { +- WREG32(EVERGREEN_DP_SEC_TIMESTAMP + dig->afmt->offset, +- EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); +- WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset, +- EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ +- EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ +- EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ +- EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ +- } else { +- WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset, 0); +- } +- +- dig->afmt->enabled = enable; +-} +--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c ++++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c +@@ -437,7 +437,7 @@ void evergreen_dp_enable(struct drm_enco + WREG32(EVERGREEN_DP_SEC_TIMESTAMP + dig->afmt->offset, + EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); + +- if (radeon_connector->con_priv) { ++ if (!ASIC_IS_DCE6(rdev) && radeon_connector->con_priv) { + dig_connector = radeon_connector->con_priv; + val = RREG32(EVERGREEN_DP_SEC_AUD_N + dig->afmt->offset); + val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf); +--- a/drivers/gpu/drm/radeon/radeon_audio.c ++++ b/drivers/gpu/drm/radeon/radeon_audio.c +@@ -102,7 +102,6 @@ static void radeon_audio_dp_mode_set(str + void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); + void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); + void evergreen_dp_enable(struct drm_encoder *encoder, bool enable); +-void dce6_dp_enable(struct drm_encoder *encoder, bool enable); + + static const u32 pin_offsets[7] = + { +@@ -240,7 +239,7 @@ static struct radeon_audio_funcs dce6_dp + .set_avi_packet = evergreen_set_avi_packet, + .set_audio_packet = dce4_set_audio_packet, + .mode_set = radeon_audio_dp_mode_set, +- .dpms = dce6_dp_enable, ++ .dpms = evergreen_dp_enable, + }; + + static void radeon_audio_interface_init(struct radeon_device *rdev) diff --git a/queue-4.0/drm-radeon-fix-lockup-when-bos-aren-t-part-of-the-vm-on-release.patch b/queue-4.0/drm-radeon-fix-lockup-when-bos-aren-t-part-of-the-vm-on-release.patch new file mode 100644 index 00000000000..4c2bafac6e3 --- /dev/null +++ b/queue-4.0/drm-radeon-fix-lockup-when-bos-aren-t-part-of-the-vm-on-release.patch @@ -0,0 +1,37 @@ +From 26d4d129b6042197b4cbc8341c0618f99231af2f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Mon, 27 Apr 2015 17:04:34 +0200 +Subject: drm/radeon: fix lockup when BOs aren't part of the VM on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Christian=20K=C3=B6nig?= + +commit 26d4d129b6042197b4cbc8341c0618f99231af2f upstream. + +If we unmap BOs before releasing them them the intervall tree locks +up because we try to remove an entry not inside the tree. + +Based on a patch from Michel Dänzer. + +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_vm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_vm.c ++++ b/drivers/gpu/drm/radeon/radeon_vm.c +@@ -1107,7 +1107,8 @@ void radeon_vm_bo_rmv(struct radeon_devi + list_del(&bo_va->bo_list); + + mutex_lock(&vm->mutex); +- interval_tree_remove(&bo_va->it, &vm->va); ++ if (bo_va->it.start || bo_va->it.last) ++ interval_tree_remove(&bo_va->it, &vm->va); + spin_lock(&vm->status_lock); + list_del(&bo_va->vm_status); + diff --git a/queue-4.0/drm-radeon-fix-ordering-of-avi-packet-setup.patch b/queue-4.0/drm-radeon-fix-ordering-of-avi-packet-setup.patch new file mode 100644 index 00000000000..d34b9505834 --- /dev/null +++ b/queue-4.0/drm-radeon-fix-ordering-of-avi-packet-setup.patch @@ -0,0 +1,62 @@ +From 304f07e9c8d302cf3183248cbabb40598eb5b732 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 31 Mar 2015 10:33:05 -0400 +Subject: drm/radeon: fix ordering of AVI packet setup + +From: Alex Deucher + +commit 304f07e9c8d302cf3183248cbabb40598eb5b732 upstream. + +Set the line first, then enable the stream. May fix +pink line problems on some displays. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/evergreen_hdmi.c | 12 ++++++------ + drivers/gpu/drm/radeon/r600_hdmi.c | 9 +++++---- + 2 files changed, 11 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c ++++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c +@@ -219,13 +219,13 @@ void evergreen_set_avi_packet(struct rad + WREG32(AFMT_AVI_INFO3 + offset, + frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); + +- WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, +- HDMI_AVI_INFO_SEND | /* enable AVI info frames */ +- HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ +- + WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset, +- HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ +- ~HDMI_AVI_INFO_LINE_MASK); ++ HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ ++ ~HDMI_AVI_INFO_LINE_MASK); ++ ++ WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset, ++ HDMI_AVI_INFO_SEND | /* enable AVI info frames */ ++ HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ + } + + void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, +--- a/drivers/gpu/drm/radeon/r600_hdmi.c ++++ b/drivers/gpu/drm/radeon/r600_hdmi.c +@@ -228,12 +228,13 @@ void r600_set_avi_packet(struct radeon_d + WREG32(HDMI0_AVI_INFO3 + offset, + frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24)); + ++ WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, ++ HDMI0_AVI_INFO_LINE(2)); /* anything other than 0 */ ++ + WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, +- HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ +- HDMI0_AVI_INFO_CONT); /* send AVI info frames every frame/field */ ++ HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ ++ HDMI0_AVI_INFO_CONT); /* send AVI info frames every frame/field */ + +- WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, +- HDMI0_AVI_INFO_LINE(2)); /* anything other than 0 */ + } + + /* diff --git a/queue-4.0/drm-radeon-only-enable-audio-streams-if-the-monitor-supports-it.patch b/queue-4.0/drm-radeon-only-enable-audio-streams-if-the-monitor-supports-it.patch new file mode 100644 index 00000000000..0b42b756fa1 --- /dev/null +++ b/queue-4.0/drm-radeon-only-enable-audio-streams-if-the-monitor-supports-it.patch @@ -0,0 +1,88 @@ +From 38aef1549b18539eaecd804383a6ccb6588a9ce1 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 7 Apr 2015 10:20:49 -0400 +Subject: drm/radeon: only enable audio streams if the monitor supports it + +From: Alex Deucher + +commit 38aef1549b18539eaecd804383a6ccb6588a9ce1 upstream. + +Selectively enable which packets we send based on monitor caps. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_encoders.c | 6 ++---- + drivers/gpu/drm/radeon/evergreen_hdmi.c | 27 +++++++++++++++++++-------- + 2 files changed, 21 insertions(+), 12 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -1729,17 +1729,15 @@ radeon_atom_encoder_dpms(struct drm_enco + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + int encoder_mode = atombios_get_encoder_mode(encoder); + + DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", + radeon_encoder->encoder_id, mode, radeon_encoder->devices, + radeon_encoder->active_device); + +- if (connector && (radeon_audio != 0) && ++ if ((radeon_audio != 0) && + ((encoder_mode == ATOM_ENCODER_MODE_HDMI) || +- (ENCODER_MODE_IS_DP(encoder_mode) && +- drm_detect_monitor_audio(radeon_connector_edid(connector))))) ++ ENCODER_MODE_IS_DP(encoder_mode))) + radeon_audio_dpms(encoder, mode); + + switch (radeon_encoder->encoder_id) { +--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c ++++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c +@@ -398,13 +398,23 @@ void evergreen_hdmi_enable(struct drm_en + return; + + if (enable) { +- WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, +- HDMI_AVI_INFO_SEND | /* enable AVI info frames */ +- HDMI_AVI_INFO_CONT | /* required for audio info values to be updated */ +- HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ +- HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ +- WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, +- AFMT_AUDIO_SAMPLE_SEND); ++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); ++ ++ if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { ++ WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, ++ HDMI_AVI_INFO_SEND | /* enable AVI info frames */ ++ HDMI_AVI_INFO_CONT | /* required for audio info values to be updated */ ++ HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ ++ HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */ ++ WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, ++ AFMT_AUDIO_SAMPLE_SEND); ++ } else { ++ WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, ++ HDMI_AVI_INFO_SEND | /* enable AVI info frames */ ++ HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */ ++ WREG32_AND(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, ++ ~AFMT_AUDIO_SAMPLE_SEND); ++ } + } else { + WREG32_AND(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset, + ~AFMT_AUDIO_SAMPLE_SEND); +@@ -423,11 +433,12 @@ void evergreen_dp_enable(struct drm_enco + struct radeon_device *rdev = dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; ++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + + if (!dig || !dig->afmt) + return; + +- if (enable) { ++ if (enable && drm_detect_monitor_audio(radeon_connector_edid(connector))) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *dig_connector; diff --git a/queue-4.0/drm-radeon-only-mark-audio-as-connected-if-the-monitor-supports-it-v3.patch b/queue-4.0/drm-radeon-only-mark-audio-as-connected-if-the-monitor-supports-it-v3.patch new file mode 100644 index 00000000000..cf65e989ac9 --- /dev/null +++ b/queue-4.0/drm-radeon-only-mark-audio-as-connected-if-the-monitor-supports-it-v3.patch @@ -0,0 +1,97 @@ +From 0f55db36d49d45b80eff0c0a2a498766016f458b Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 7 Apr 2015 09:52:42 -0400 +Subject: drm/radeon: only mark audio as connected if the monitor supports it (v3) + +From: Alex Deucher + +commit 0f55db36d49d45b80eff0c0a2a498766016f458b upstream. + +Otherwise the driver may try and send audio which may confuse the +monitor. + +v2: set pin to NULL if no audio +v3: avoid crash with analog encoders + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_audio.c | 27 +++++++++++++++------------ + drivers/gpu/drm/radeon/radeon_connectors.c | 8 ++++++-- + 2 files changed, 21 insertions(+), 14 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_audio.c ++++ b/drivers/gpu/drm/radeon/radeon_audio.c +@@ -460,30 +460,33 @@ void radeon_audio_detect(struct drm_conn + if (!connector || !connector->encoder) + return; + ++ if (!radeon_encoder_is_digital(connector->encoder)) ++ return; ++ + rdev = connector->encoder->dev->dev_private; + radeon_encoder = to_radeon_encoder(connector->encoder); + dig = radeon_encoder->enc_priv; + +- if (status == connector_status_connected) { +- struct radeon_connector *radeon_connector; +- int sink_type; +- +- if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { +- radeon_encoder->audio = NULL; +- return; +- } ++ if (!dig->afmt) ++ return; + +- radeon_connector = to_radeon_connector(connector); +- sink_type = radeon_dp_getsinktype(radeon_connector); ++ if (status == connector_status_connected) { ++ struct radeon_connector *radeon_connector = to_radeon_connector(connector); + + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && +- sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ++ radeon_dp_getsinktype(radeon_connector) == ++ CONNECTOR_OBJECT_ID_DISPLAYPORT) + radeon_encoder->audio = rdev->audio.dp_funcs; + else + radeon_encoder->audio = rdev->audio.hdmi_funcs; + + dig->afmt->pin = radeon_audio_get_pin(connector->encoder); +- radeon_audio_enable(rdev, dig->afmt->pin, 0xf); ++ if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { ++ radeon_audio_enable(rdev, dig->afmt->pin, 0xf); ++ } else { ++ radeon_audio_enable(rdev, dig->afmt->pin, 0); ++ dig->afmt->pin = NULL; ++ } + } else { + radeon_audio_enable(rdev, dig->afmt->pin, 0); + dig->afmt->pin = NULL; +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -1333,8 +1333,10 @@ out: + /* updated in get modes as well since we need to know if it's analog or digital */ + radeon_connector_update_scratch_regs(connector, ret); + +- if (radeon_audio != 0) ++ if (radeon_audio != 0) { ++ radeon_connector_get_edid(connector); + radeon_audio_detect(connector, ret); ++ } + + exit: + pm_runtime_mark_last_busy(connector->dev->dev); +@@ -1659,8 +1661,10 @@ radeon_dp_detect(struct drm_connector *c + + radeon_connector_update_scratch_regs(connector, ret); + +- if (radeon_audio != 0) ++ if (radeon_audio != 0) { ++ radeon_connector_get_edid(connector); + radeon_audio_detect(connector, ret); ++ } + + out: + pm_runtime_mark_last_busy(connector->dev->dev); diff --git a/queue-4.0/drm-radeon-reset-bos-address-after-clearing-it.patch b/queue-4.0/drm-radeon-reset-bos-address-after-clearing-it.patch new file mode 100644 index 00000000000..2f8f1b5dce5 --- /dev/null +++ b/queue-4.0/drm-radeon-reset-bos-address-after-clearing-it.patch @@ -0,0 +1,34 @@ +From 48afbd70ac7b6aa62e8d452091023941d8085f8a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= +Date: Mon, 27 Apr 2015 17:04:35 +0200 +Subject: drm/radeon: reset BOs address after clearing it. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Christian=20K=C3=B6nig?= + +commit 48afbd70ac7b6aa62e8d452091023941d8085f8a upstream. + +Otherwise it is possible that we will have page table corruption +if we change a BOs address multiple times. + +Signed-off-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_vm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/radeon/radeon_vm.c ++++ b/drivers/gpu/drm/radeon/radeon_vm.c +@@ -490,6 +490,8 @@ int radeon_vm_bo_set_addr(struct radeon_ + spin_lock(&vm->status_lock); + list_add(&tmp->vm_status, &vm->freed); + spin_unlock(&vm->status_lock); ++ ++ bo_va->addr = 0; + } + + interval_tree_remove(&bo_va->it, &vm->va); diff --git a/queue-4.0/drm-radeon-use-drm_calloc_ab-for-cs-relocs.patch b/queue-4.0/drm-radeon-use-drm_calloc_ab-for-cs-relocs.patch new file mode 100644 index 00000000000..bc4e9c19688 --- /dev/null +++ b/queue-4.0/drm-radeon-use-drm_calloc_ab-for-cs-relocs.patch @@ -0,0 +1,44 @@ +From b421ed15d2c3039eb724680e4de1e4b2bd196a9a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +Date: Thu, 16 Apr 2015 11:17:27 +0900 +Subject: drm/radeon: Use drm_calloc_ab for CS relocs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= + +commit b421ed15d2c3039eb724680e4de1e4b2bd196a9a upstream. + +The number of relocs is passed in by userspace and can be large. It has +been observed to cause kcalloc failures in the wild. + +Reviewed-by: Christian König +Signed-off-by: Michel Dänzer +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_cs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_cs.c ++++ b/drivers/gpu/drm/radeon/radeon_cs.c +@@ -88,7 +88,7 @@ static int radeon_cs_parser_relocs(struc + p->dma_reloc_idx = 0; + /* FIXME: we assume that each relocs use 4 dwords */ + p->nrelocs = chunk->length_dw / 4; +- p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_bo_list), GFP_KERNEL); ++ p->relocs = drm_calloc_large(p->nrelocs, sizeof(struct radeon_bo_list)); + if (p->relocs == NULL) { + return -ENOMEM; + } +@@ -428,7 +428,7 @@ static void radeon_cs_parser_fini(struct + } + } + kfree(parser->track); +- kfree(parser->relocs); ++ drm_free_large(parser->relocs); + drm_free_large(parser->vm_bos); + for (i = 0; i < parser->nchunks; i++) + drm_free_large(parser->chunks[i].kdata); diff --git a/queue-4.0/hfsplus-don-t-store-special-osx-xattr-prefix-on-disk.patch b/queue-4.0/hfsplus-don-t-store-special-osx-xattr-prefix-on-disk.patch new file mode 100644 index 00000000000..4a2fc0cc267 --- /dev/null +++ b/queue-4.0/hfsplus-don-t-store-special-osx-xattr-prefix-on-disk.patch @@ -0,0 +1,140 @@ +From db579e76f06e78de011b2cb7e028740a82f5558c Mon Sep 17 00:00:00 2001 +From: Thomas Hebb +Date: Thu, 16 Apr 2015 12:47:18 -0700 +Subject: hfsplus: don't store special "osx" xattr prefix on-disk + +From: Thomas Hebb + +commit db579e76f06e78de011b2cb7e028740a82f5558c upstream. + +On Mac OS X, HFS+ extended attributes are not namespaced. Since we want +to be compatible with OS X filesystems and yet still support the Linux +namespacing system, the hfsplus driver implements a special "osx" +namespace that is reported for any attribute that is not namespaced +on-disk. However, the current code for getting and setting these +unprefixed attributes is broken. + +hfsplus_osx_setattr() and hfsplus_osx_getattr() are passed names that have +already had their "osx." prefixes stripped by the generic functions. The +functions first, quite correctly, check those names to make sure that they +aren't prefixed with a known namespace, which would allow namespace access +restrictions to be bypassed. However, the functions then prepend "osx." +to the name they're given before passing it on to hfsplus_getattr() and +hfsplus_setattr(). Not only does this cause the "osx." prefix to be +stored on-disk, defeating its purpose, it also breaks the check for the +special "com.apple.FinderInfo" attribute, which is reported for all files, +and as a consequence makes some userspace applications (e.g. GNU patch) +fail even when extended attributes are not otherwise in use. + +There are five commits which have touched this particular code: + + 127e5f5ae51e ("hfsplus: rework functionality of getting, setting and deleting of extended attributes") + b168fff72109 ("hfsplus: use xattr handlers for removexattr") + bf29e886b242 ("hfsplus: correct usage of HFSPLUS_ATTR_MAX_STRLEN for non-English attributes") + fcacbd95e121 ("fs/hfsplus: move xattr_name allocation in hfsplus_getxattr()") + ec1bbd346f18 ("fs/hfsplus: move xattr_name allocation in hfsplus_setxattr()") + +The first commit creates the functions to begin with. The namespace is +prepended by the original code, which I believe was correct at the time, +since hfsplus_?etattr() stripped the prefix if found. The second commit +removes this behavior from hfsplus_?etattr() and appears to have been +intended to also remove the prefixing from hfsplus_osx_?etattr(). +However, what it actually does is remove a necessary strncpy() call +completely, breaking the osx namespace entirely. The third commit re-adds +the strncpy() call as it was originally, but doesn't mention it in its +commit message. The final two commits refactor the code and don't affect +its functionality. + +This commit does what b168fff attempted to do (prevent the prefix from +being added), but does it properly, instead of passing in an empty buffer +(which is what b168fff actually did). + +Fixes: b168fff72109 ("hfsplus: use xattr handlers for removexattr") +Signed-off-by: Thomas Hebb +Cc: Hin-Tak Leung +Cc: Sergei Antonov +Cc: Anton Altaparmakov +Cc: Fabian Frederick +Cc: Christian Kujau +Cc: Christoph Hellwig +Cc: Al Viro +Cc: Viacheslav Dubeyko +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Thomas Hebb +Signed-off-by: Greg Kroah-Hartman +--- + fs/hfsplus/xattr.c | 42 ++++++++++++++++-------------------------- + 1 file changed, 16 insertions(+), 26 deletions(-) + +--- a/fs/hfsplus/xattr.c ++++ b/fs/hfsplus/xattr.c +@@ -806,9 +806,6 @@ end_removexattr: + static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name, + void *buffer, size_t size, int type) + { +- char *xattr_name; +- int res; +- + if (!strcmp(name, "")) + return -EINVAL; + +@@ -818,24 +815,19 @@ static int hfsplus_osx_getxattr(struct d + */ + if (is_known_namespace(name)) + return -EOPNOTSUPP; +- xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN +- + XATTR_MAC_OSX_PREFIX_LEN + 1, GFP_KERNEL); +- if (!xattr_name) +- return -ENOMEM; +- strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); +- strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); +- +- res = hfsplus_getxattr(dentry, xattr_name, buffer, size); +- kfree(xattr_name); +- return res; ++ ++ /* ++ * osx is the namespace we use to indicate an unprefixed ++ * attribute on the filesystem (like the ones that OS X ++ * creates), so we pass the name through unmodified (after ++ * ensuring it doesn't conflict with another namespace). ++ */ ++ return hfsplus_getxattr(dentry, name, buffer, size); + } + + static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, int type) + { +- char *xattr_name; +- int res; +- + if (!strcmp(name, "")) + return -EINVAL; + +@@ -845,16 +837,14 @@ static int hfsplus_osx_setxattr(struct d + */ + if (is_known_namespace(name)) + return -EOPNOTSUPP; +- xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN +- + XATTR_MAC_OSX_PREFIX_LEN + 1, GFP_KERNEL); +- if (!xattr_name) +- return -ENOMEM; +- strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); +- strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); +- +- res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); +- kfree(xattr_name); +- return res; ++ ++ /* ++ * osx is the namespace we use to indicate an unprefixed ++ * attribute on the filesystem (like the ones that OS X ++ * creates), so we pass the name through unmodified (after ++ * ensuring it doesn't conflict with another namespace). ++ */ ++ return hfsplus_setxattr(dentry, name, buffer, size, flags); + } + + static size_t hfsplus_osx_listxattr(struct dentry *dentry, char *list, diff --git a/queue-4.0/scsi-add-1024-max-sectors-black-list-flag.patch b/queue-4.0/scsi-add-1024-max-sectors-black-list-flag.patch new file mode 100644 index 00000000000..091f152fade --- /dev/null +++ b/queue-4.0/scsi-add-1024-max-sectors-black-list-flag.patch @@ -0,0 +1,94 @@ +From 35e9a9f93994d7f7d12afa41169c7ba05513721b Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Mon, 20 Apr 2015 22:42:24 -0500 +Subject: SCSI: add 1024 max sectors black list flag + +From: Mike Christie + +commit 35e9a9f93994d7f7d12afa41169c7ba05513721b upstream. + +This works around a issue with qnap iscsi targets not handling large IOs +very well. + +The target returns: + +VPD INQUIRY: Block limits page (SBC) + Maximum compare and write length: 1 blocks + Optimal transfer length granularity: 1 blocks + Maximum transfer length: 4294967295 blocks + Optimal transfer length: 4294967295 blocks + Maximum prefetch, xdread, xdwrite transfer length: 0 blocks + Maximum unmap LBA count: 8388607 + Maximum unmap block descriptor count: 1 + Optimal unmap granularity: 16383 + Unmap granularity alignment valid: 0 + Unmap granularity alignment: 0 + Maximum write same length: 0xffffffff blocks + Maximum atomic transfer length: 0 + Atomic alignment: 0 + Atomic transfer length granularity: 0 + +and it is *sometimes* able to handle at least one IO of size up to 8 MB. We +have seen in traces where it will sometimes work, but other times it +looks like it fails and it looks like it returns failures if we send +multiple large IOs sometimes. Also it looks like it can return 2 different +errors. It will sometimes send iscsi reject errors indicating out of +resources or it will send invalid cdb illegal requests check conditions. +And then when it sends iscsi rejects it does not seem to handle retries +when there are command sequence holes, so I could not just add code to +try and gracefully handle that error code. + +The problem is that we do not have a good contact for the company, +so we are not able to determine under what conditions it returns +which error and why it sometimes works. + +So, this patch just adds a new black list flag to set targets like this to +the old max safe sectors of 1024. The max_hw_sectors changes added in 3.19 +caused this regression, so I also ccing stable. + +Reported-by: Christian Hesse +Signed-off-by: Mike Christie +Reviewed-by: Christoph Hellwig +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_devinfo.c | 1 + + drivers/scsi/scsi_scan.c | 6 ++++++ + include/scsi/scsi_devinfo.h | 1 + + 3 files changed, 8 insertions(+) + +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -226,6 +226,7 @@ static struct { + {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC}, + {"Promise", "", NULL, BLIST_SPARSELUN}, ++ {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024}, + {"QUANTUM", "XP34301", "1071", BLIST_NOTQ}, + {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, + {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -897,6 +897,12 @@ static int scsi_add_lun(struct scsi_devi + */ + if (*bflags & BLIST_MAX_512) + blk_queue_max_hw_sectors(sdev->request_queue, 512); ++ /* ++ * Max 1024 sector transfer length for targets that report incorrect ++ * max/optimal lengths and relied on the old block layer safe default ++ */ ++ else if (*bflags & BLIST_MAX_1024) ++ blk_queue_max_hw_sectors(sdev->request_queue, 1024); + + /* + * Some devices may not want to have a start command automatically +--- a/include/scsi/scsi_devinfo.h ++++ b/include/scsi/scsi_devinfo.h +@@ -36,5 +36,6 @@ + for sequential scan */ + #define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */ + #define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */ ++#define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */ + + #endif diff --git a/queue-4.0/series b/queue-4.0/series index 31d1d8d57f6..9cc86af7174 100644 --- a/queue-4.0/series +++ b/queue-4.0/series @@ -53,3 +53,19 @@ uas-add-us_fl_max_sectors_240-flag.patch uas-set-max_sectors_240-quirk-for-asm1053-devices.patch ext4-fix-data-corruption-caused-by-unwritten-and-delayed-extents.patch ext4-move-check-under-lock-scope-to-close-a-race.patch +scsi-add-1024-max-sectors-black-list-flag.patch +3w-xxxx-fix-command-completion-race.patch +3w-9xxx-fix-command-completion-race.patch +3w-sas-fix-command-completion-race.patch +drm-radeon-fix-ordering-of-avi-packet-setup.patch +drm-radeon-drop-dce6_dp_enable.patch +drm-radeon-audio-don-t-enable-packets-until-the-end.patch +drm-radeon-only-mark-audio-as-connected-if-the-monitor-supports-it-v3.patch +drm-radeon-only-enable-audio-streams-if-the-monitor-supports-it.patch +drm-radeon-use-drm_calloc_ab-for-cs-relocs.patch +drm-radeon-adjust-pll-when-audio-is-not-enabled.patch +drm-radeon-add-si-dpm-quirk-for-sapphire-r9-270-dual-x-2g-gddr5.patch +drm-radeon-fix-lockup-when-bos-aren-t-part-of-the-vm-on-release.patch +drm-radeon-reset-bos-address-after-clearing-it.patch +drm-radeon-check-new-address-before-removing-old-one.patch +hfsplus-don-t-store-special-osx-xattr-prefix-on-disk.patch