diff --git a/debian/changelog b/debian/changelog index 6c555d066..945a2eb43 100644 --- a/debian/changelog +++ b/debian/changelog @@ -32,7 +32,16 @@ linux-2.6 (2.6.29~rc5-1~experimental.1) UNRELEASED; urgency=low the option cannot be made modular at the moment and bloats the kernel image too much. - -- maximilian attems Thu, 19 Feb 2009 13:25:20 +0100 + [ Ben Hutchings ] + * Remove firmware from drivers and make them use request_firmware(): + - mga (closes: #502666) + - qla1280 (closes: #502667) + - r128 (closes: #494007) + - radeon (closes: #494009) + - tehuti (closes: #501153) + - typhoon (closes: #502669) + + -- Ben Hutchings Sun, 22 Feb 2009 03:14:38 +0000 linux-2.6 (2.6.28-2) UNRELEASED; urgency=low diff --git a/debian/patches/debian/dfsg/files-1 b/debian/patches/debian/dfsg/files-1 index bc05d8bca..a700f8261 100644 --- a/debian/patches/debian/dfsg/files-1 +++ b/debian/patches/debian/dfsg/files-1 @@ -23,6 +23,12 @@ rm firmware/ttusb-budget rm firmware/vicam rm firmware/yamaha +rm drivers/gpu/drm/mga/mga_ucode.h + +unifdef drivers/gpu/drm/r128/r128_cce.c -UREMOVE_DFSG + +rm drivers/gpu/drm/radeon/radeon_microcode.h + rm drivers/net/appletalk/cops.c rm drivers/net/appletalk/cops.h rm drivers/net/appletalk/cops_ffdrv.h @@ -38,10 +44,18 @@ rm drivers/net/hamradio/yam9600.h rm drivers/net/myri_code.h +rm drivers/net/tehuti_fw.h + rm drivers/net/tokenring/3c359.c rm drivers/net/tokenring/3c359.h rm drivers/net/tokenring/3c359_microcode.h +rm drivers/net/typhoon-firmware.h + +rm drivers/scsi/ql1040_fw.h +rm drivers/scsi/ql12160_fw.h +rm drivers/scsi/ql1280_fw.h + rm drivers/scsi/qlogicpti_asm.c rm sound/pci/cs46xx/cs46xx_image.h diff --git a/debian/patches/features/all/drivers-gpu-drm-mga-request_firmware.patch b/debian/patches/features/all/drivers-gpu-drm-mga-request_firmware.patch new file mode 100644 index 000000000..43d974523 --- /dev/null +++ b/debian/patches/features/all/drivers-gpu-drm-mga-request_firmware.patch @@ -0,0 +1,295 @@ +From 0175b4bdefff22f837203fd47f568c4647f24a4f Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sat, 18 Oct 2008 04:28:10 +0100 +Subject: [PATCH 18/24] mga: Use request_firmware() to load microcode + +Image format is IHEX, one record for each pipe in order (record +addresses are ignored). + +Compile-tested only. +--- + drivers/gpu/drm/Kconfig | 2 +- + drivers/gpu/drm/mga/mga_dma.c | 4 +- + drivers/gpu/drm/mga/mga_drv.h | 1 - + drivers/gpu/drm/mga/mga_warp.c | 180 +++++++++++++++++----------------------- + include/drm/mga_drm.h | 2 +- + 5 files changed, 82 insertions(+), 107 deletions(-) + +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index 853814c..a61d10a 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -81,7 +81,7 @@ endchoice + config DRM_MGA + tristate "Matrox g200/g400" + depends on DRM +- depends on BROKEN ++ select FW_LOADER + help + Choose this option if you have a Matrox G200, G400 or G450 graphics + card. If M is selected, the module will be called mga. AGP +diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c +index b49c5ff..7e0b106 100644 +--- a/drivers/gpu/drm/mga/mga_dma.c ++++ b/drivers/gpu/drm/mga/mga_dma.c +@@ -447,7 +447,7 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, + { + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; +- unsigned int warp_size = mga_warp_microcode_size(dev_priv); ++ unsigned int warp_size = MGA_WARP_UCODE_SIZE; + int err; + unsigned offset; + const unsigned secondary_size = dma_bs->secondary_bin_count +@@ -622,7 +622,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev, + { + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; +- unsigned int warp_size = mga_warp_microcode_size(dev_priv); ++ unsigned int warp_size = MGA_WARP_UCODE_SIZE; + unsigned int primary_size; + unsigned int bin_count; + int err; +diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h +index 88257c2..9e40226 100644 +--- a/drivers/gpu/drm/mga/mga_drv.h ++++ b/drivers/gpu/drm/mga/mga_drv.h +@@ -177,7 +177,6 @@ extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv); + extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf); + + /* mga_warp.c */ +-extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv); + extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); + extern int mga_warp_init(drm_mga_private_t * dev_priv); + +diff --git a/drivers/gpu/drm/mga/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c +index 651b93c..9aad484 100644 +--- a/drivers/gpu/drm/mga/mga_warp.c ++++ b/drivers/gpu/drm/mga/mga_warp.c +@@ -27,132 +27,108 @@ + * Gareth Hughes + */ + ++#include ++#include ++#include ++ + #include "drmP.h" + #include "drm.h" + #include "mga_drm.h" + #include "mga_drv.h" +-#include "mga_ucode.h" ++ ++#define FIRMWARE_G200 "matrox/g200_warp.fw" ++#define FIRMWARE_G400 "matrox/g400_warp.fw" ++ ++MODULE_FIRMWARE(FIRMWARE_G200); ++MODULE_FIRMWARE(FIRMWARE_G400); + + #define MGA_WARP_CODE_ALIGN 256 /* in bytes */ + +-#define WARP_UCODE_SIZE( which ) \ +- ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) +- +-#define WARP_UCODE_INSTALL( which, where ) \ +-do { \ +- DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\ +- dev_priv->warp_pipe_phys[where] = pcbase; \ +- memcpy( vcbase, which, sizeof(which) ); \ +- pcbase += WARP_UCODE_SIZE( which ); \ +- vcbase += WARP_UCODE_SIZE( which ); \ +-} while (0) +- +-static const unsigned int mga_warp_g400_microcode_size = +- (WARP_UCODE_SIZE(warp_g400_tgz) + +- WARP_UCODE_SIZE(warp_g400_tgza) + +- WARP_UCODE_SIZE(warp_g400_tgzaf) + +- WARP_UCODE_SIZE(warp_g400_tgzf) + +- WARP_UCODE_SIZE(warp_g400_tgzs) + +- WARP_UCODE_SIZE(warp_g400_tgzsa) + +- WARP_UCODE_SIZE(warp_g400_tgzsaf) + +- WARP_UCODE_SIZE(warp_g400_tgzsf) + +- WARP_UCODE_SIZE(warp_g400_t2gz) + +- WARP_UCODE_SIZE(warp_g400_t2gza) + +- WARP_UCODE_SIZE(warp_g400_t2gzaf) + +- WARP_UCODE_SIZE(warp_g400_t2gzf) + +- WARP_UCODE_SIZE(warp_g400_t2gzs) + +- WARP_UCODE_SIZE(warp_g400_t2gzsa) + +- WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf)); +- +-static const unsigned int mga_warp_g200_microcode_size = +- (WARP_UCODE_SIZE(warp_g200_tgz) + +- WARP_UCODE_SIZE(warp_g200_tgza) + +- WARP_UCODE_SIZE(warp_g200_tgzaf) + +- WARP_UCODE_SIZE(warp_g200_tgzf) + +- WARP_UCODE_SIZE(warp_g200_tgzs) + +- WARP_UCODE_SIZE(warp_g200_tgzsa) + +- WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf)); +- +-unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv) ++#define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN) ++ ++int mga_warp_install_microcode(drm_mga_private_t * dev_priv) + { ++ unsigned char *vcbase = dev_priv->warp->handle; ++ unsigned long pcbase = dev_priv->warp->offset; ++ const char *firmware_name; ++ struct platform_device *pdev; ++ const struct firmware *fw = NULL; ++ const struct ihex_binrec *rec; ++ unsigned int size; ++ int n_pipes, where; ++ int rc = 0; ++ + switch (dev_priv->chipset) { + case MGA_CARD_TYPE_G400: + case MGA_CARD_TYPE_G550: +- return PAGE_ALIGN(mga_warp_g400_microcode_size); ++ firmware_name = FIRMWARE_G400; ++ n_pipes = MGA_MAX_G400_PIPES; ++ break; + case MGA_CARD_TYPE_G200: +- return PAGE_ALIGN(mga_warp_g200_microcode_size); ++ firmware_name = FIRMWARE_G200; ++ n_pipes = MGA_MAX_G200_PIPES; ++ break; + default: +- return 0; ++ return -EINVAL; + } +-} +- +-static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv) +-{ +- unsigned char *vcbase = dev_priv->warp->handle; +- unsigned long pcbase = dev_priv->warp->offset; +- +- memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); +- +- WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ); +- WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF); +- WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA); +- WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF); +- WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS); +- WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF); +- WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA); +- WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF); +- +- WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ); +- WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF); +- WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA); +- WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF); +- WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS); +- WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF); +- WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA); +- WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF); +- +- return 0; +-} +- +-static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv) +-{ +- unsigned char *vcbase = dev_priv->warp->handle; +- unsigned long pcbase = dev_priv->warp->offset; +- +- memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); +- +- WARP_UCODE_INSTALL(warp_g200_tgz, MGA_WARP_TGZ); +- WARP_UCODE_INSTALL(warp_g200_tgzf, MGA_WARP_TGZF); +- WARP_UCODE_INSTALL(warp_g200_tgza, MGA_WARP_TGZA); +- WARP_UCODE_INSTALL(warp_g200_tgzaf, MGA_WARP_TGZAF); +- WARP_UCODE_INSTALL(warp_g200_tgzs, MGA_WARP_TGZS); +- WARP_UCODE_INSTALL(warp_g200_tgzsf, MGA_WARP_TGZSF); +- WARP_UCODE_INSTALL(warp_g200_tgzsa, MGA_WARP_TGZSA); +- WARP_UCODE_INSTALL(warp_g200_tgzsaf, MGA_WARP_TGZSAF); + +- return 0; +-} ++ pdev = platform_device_register_simple("mga_warp", 0, NULL, 0); ++ if (IS_ERR(pdev)) { ++ DRM_ERROR("mga: Failed to register microcode\n"); ++ return PTR_ERR(pdev); ++ } ++ rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); ++ platform_device_unregister(pdev); ++ if (rc) { ++ DRM_ERROR("mga: Failed to load microcode \"%s\"\n", ++ firmware_name); ++ return rc; ++ } + +-int mga_warp_install_microcode(drm_mga_private_t * dev_priv) +-{ +- const unsigned int size = mga_warp_microcode_size(dev_priv); ++ size = 0; ++ where = 0; ++ for (rec = (const struct ihex_binrec *)fw->data; ++ rec; ++ rec = ihex_next_binrec(rec)) { ++ size += WARP_UCODE_SIZE(be16_to_cpu(rec->len)); ++ where++; ++ } + ++ if (where != n_pipes) { ++ DRM_ERROR("mga: Invalid microcode \"%s\"\n", firmware_name); ++ rc = -EINVAL; ++ goto out; ++ } ++ size = PAGE_ALIGN(size); + DRM_DEBUG("MGA ucode size = %d bytes\n", size); + if (size > dev_priv->warp->size) { + DRM_ERROR("microcode too large! (%u > %lu)\n", + size, dev_priv->warp->size); +- return -ENOMEM; ++ rc = -ENOMEM; ++ goto out; + } + +- switch (dev_priv->chipset) { +- case MGA_CARD_TYPE_G400: +- case MGA_CARD_TYPE_G550: +- return mga_warp_install_g400_microcode(dev_priv); +- case MGA_CARD_TYPE_G200: +- return mga_warp_install_g200_microcode(dev_priv); +- default: +- return -EINVAL; ++ memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); ++ ++ where = 0; ++ for (rec = (const struct ihex_binrec *)fw->data; ++ rec; ++ rec = ihex_next_binrec(rec)) { ++ unsigned int src_size, dst_size; ++ ++ DRM_DEBUG(" pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase); ++ dev_priv->warp_pipe_phys[where] = pcbase; ++ src_size = be16_to_cpu(rec->len); ++ dst_size = WARP_UCODE_SIZE(src_size); ++ memcpy(vcbase, rec->data, src_size); ++ pcbase += dst_size; ++ vcbase += dst_size; ++ where++; + } ++ ++out: ++ release_firmware(fw); ++ return rc; + } + + #define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) +diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h +index 944b50a..0b8fc27 100644 +--- a/include/drm/mga_drm.h ++++ b/include/drm/mga_drm.h +@@ -69,7 +69,7 @@ + #define MGA_MAX_G200_PIPES 8 /* no multitex */ + #define MGA_MAX_G400_PIPES 16 + #define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES +-#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */ ++#define MGA_WARP_UCODE_SIZE 40960 /* in bytes */ + + #define MGA_CARD_TYPE_G200 1 + #define MGA_CARD_TYPE_G400 2 +-- +1.6.1.3 + diff --git a/debian/patches/features/all/drivers-gpu-drm-r128-request_firmware.patch b/debian/patches/features/all/drivers-gpu-drm-r128-request_firmware.patch new file mode 100644 index 000000000..00f0d79ae --- /dev/null +++ b/debian/patches/features/all/drivers-gpu-drm-r128-request_firmware.patch @@ -0,0 +1,139 @@ +From 870bed4eea53fbaeb8f585fb9b89d23d9d8c2436 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sat, 18 Oct 2008 02:27:57 +0100 +Subject: [PATCH 03/24] r128: Use request_firmware() to load CCE microcode + +Firmware blob looks like this: + __be32 datah + __be32 datal + +Compile-tested only. +--- + drivers/gpu/drm/Kconfig | 2 +- + drivers/gpu/drm/r128/r128_cce.c | 54 ++++++++++++++++++++++++++++++++++---- + 2 files changed, 49 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index 725f244..e6f4401 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -26,7 +26,7 @@ config DRM_TDFX + config DRM_R128 + tristate "ATI Rage 128" + depends on DRM && PCI +- depends on BROKEN ++ select FW_LOADER + help + Choose this option if you have an ATI Rage 128 graphics card. If M + is selected, the module will be called r128. AGP support for +diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c +index a9ee89a..63bed21 100644 +--- a/drivers/gpu/drm/r128/r128_cce.c ++++ b/drivers/gpu/drm/r128/r128_cce.c +@@ -29,6 +29,9 @@ + * Gareth Hughes + */ + ++#include ++#include ++ + #include "drmP.h" + #include "drm.h" + #include "r128_drm.h" +@@ -36,6 +39,9 @@ + + #define R128_FIFO_DEBUG 0 + ++#define FIRMWARE_NAME "r128/r128_cce.bin" ++ ++MODULE_FIRMWARE(FIRMWARE_NAME); + + static int R128_READ_PLL(struct drm_device * dev, int addr) + { +@@ -132,20 +138,50 @@ static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) + */ + + /* Load the microcode for the CCE */ +-static void r128_cce_load_microcode(drm_r128_private_t * dev_priv) ++static int r128_cce_load_microcode(drm_r128_private_t *dev_priv) + { +- int i; ++ struct platform_device *pdev; ++ const struct firmware *fw; ++ const __be32 *fw_data; ++ int rc, i; + + DRM_DEBUG("\n"); + ++ pdev = platform_device_register_simple("r128_cce", 0, NULL, 0); ++ if (IS_ERR(pdev)) { ++ printk(KERN_ERR "r128_cce: Failed to register firmware\n"); ++ return PTR_ERR(pdev); ++ } ++ rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev); ++ platform_device_unregister(pdev); ++ if (rc) { ++ printk(KERN_ERR "r128_cce: Failed to load firmware \"%s\"\n", ++ FIRMWARE_NAME); ++ return rc; ++ } ++ ++ if (fw->size != 256 * 8) { ++ printk(KERN_ERR ++ "r128_cce: Bogus length %zu in firmware \"%s\"\n", ++ fw->size, FIRMWARE_NAME); ++ rc = -EINVAL; ++ goto out_release; ++ } ++ + r128_do_wait_for_idle(dev_priv); + ++ fw_data = (const __be32 *)fw->data; + R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); + for (i = 0; i < 256; i++) { +- R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]); ++ R128_WRITE(R128_PM4_MICROCODE_DATAH, ++ be32_to_cpup(&fw_data[i * 2])); + R128_WRITE(R128_PM4_MICROCODE_DATAL, +- r128_cce_microcode[i * 2 + 1]); ++ be32_to_cpup(&fw_data[i * 2 + 1])); + } ++ ++out_release: ++ release_firmware(fw); ++ return rc; + } + + /* Flush any pending commands to the CCE. This should only be used just +@@ -306,6 +342,7 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev, + static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) + { + drm_r128_private_t *dev_priv; ++ int rc; + + DRM_DEBUG("\n"); + +@@ -532,13 +569,18 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) + #endif + + r128_cce_init_ring_buffer(dev, dev_priv); +- r128_cce_load_microcode(dev_priv); ++ rc = r128_cce_load_microcode(dev_priv); + + dev->dev_private = (void *)dev_priv; + + r128_do_engine_reset(dev); + +- return 0; ++ if (rc) { ++ DRM_ERROR("Failed to load firmware!\n"); ++ r128_do_cleanup_cce(dev); ++ } ++ ++ return rc; + } + + int r128_do_cleanup_cce(struct drm_device * dev) +-- +1.6.1.3 + diff --git a/debian/patches/features/all/drivers-gpu-drm-radeon-request_firmware.patch b/debian/patches/features/all/drivers-gpu-drm-radeon-request_firmware.patch new file mode 100644 index 000000000..d469a06ec --- /dev/null +++ b/debian/patches/features/all/drivers-gpu-drm-radeon-request_firmware.patch @@ -0,0 +1,239 @@ +From 3e3f2f1f9514969b9df1b64a9a12a7a5a1aa7550 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Wed, 15 Oct 2008 01:29:35 +0100 +Subject: [PATCH 06/24] radeon: Use request_firmware() to load CP microcode + +Tested on Radeon 7500 (RV200) with and without firmware installed. +--- + drivers/gpu/drm/Kconfig | 2 +- + drivers/gpu/drm/radeon/radeon_cp.c | 115 +++++++++++++++++++++++------------ + drivers/gpu/drm/radeon/radeon_drv.h | 6 ++ + 3 files changed, 83 insertions(+), 40 deletions(-) + +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index a93d249..09ed655 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -35,7 +35,7 @@ config DRM_R128 + config DRM_RADEON + tristate "ATI Radeon" + depends on DRM && PCI +- depends on BROKEN ++ select FW_LOADER + help + Choose this option if you have an ATI Radeon graphics card. There + are both PCI and AGP versions. You don't need to choose this to +diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c +index dcebb4b..a460149 100644 +--- a/drivers/gpu/drm/radeon/radeon_cp.c ++++ b/drivers/gpu/drm/radeon/radeon_cp.c +@@ -35,10 +35,23 @@ + #include "radeon_drv.h" + #include "r300_reg.h" + +-#include "radeon_microcode.h" +- + #define RADEON_FIFO_DEBUG 0 + ++/* Firmware Names */ ++#define FIRMWARE_R100 "radeon/R100_cp.bin" ++#define FIRMWARE_R200 "radeon/R200_cp.bin" ++#define FIRMWARE_R300 "radeon/R300_cp.bin" ++#define FIRMWARE_R420 "radeon/R420_cp.bin" ++#define FIRMWARE_RS690 "radeon/RS690_cp.bin" ++#define FIRMWARE_R520 "radeon/R520_cp.bin" ++ ++MODULE_FIRMWARE(FIRMWARE_R100); ++MODULE_FIRMWARE(FIRMWARE_R200); ++MODULE_FIRMWARE(FIRMWARE_R300); ++MODULE_FIRMWARE(FIRMWARE_R420); ++MODULE_FIRMWARE(FIRMWARE_RS690); ++MODULE_FIRMWARE(FIRMWARE_R520); ++ + static int radeon_do_cleanup_cp(struct drm_device * dev); + static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); + +@@ -318,37 +331,34 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) + */ + + /* Load the microcode for the CP */ +-static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) ++static int radeon_cp_init_microcode(drm_radeon_private_t *dev_priv) + { +- int i; ++ struct platform_device *pdev; ++ const char *fw_name = NULL; ++ int err; ++ + DRM_DEBUG("\n"); + +- radeon_do_wait_for_idle(dev_priv); ++ pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); ++ err = IS_ERR(pdev); ++ if (err) { ++ printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); ++ return -EINVAL; ++ } + +- RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) { + DRM_INFO("Loading R100 Microcode\n"); +- for (i = 0; i < 256; i++) { +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, +- R100_cp_microcode[i][1]); +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, +- R100_cp_microcode[i][0]); +- } ++ fw_name = FIRMWARE_R100; + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) { + DRM_INFO("Loading R200 Microcode\n"); +- for (i = 0; i < 256; i++) { +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, +- R200_cp_microcode[i][1]); +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, +- R200_cp_microcode[i][0]); +- } ++ fw_name = FIRMWARE_R200; + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || +@@ -356,31 +366,16 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { + DRM_INFO("Loading R300 Microcode\n"); +- for (i = 0; i < 256; i++) { +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, +- R300_cp_microcode[i][1]); +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, +- R300_cp_microcode[i][0]); +- } ++ fw_name = FIRMWARE_R300; + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { + DRM_INFO("Loading R400 Microcode\n"); +- for (i = 0; i < 256; i++) { +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, +- R420_cp_microcode[i][1]); +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, +- R420_cp_microcode[i][0]); +- } ++ fw_name = FIRMWARE_R420; + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + DRM_INFO("Loading RS690/RS740 Microcode\n"); +- for (i = 0; i < 256; i++) { +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, +- RS690_cp_microcode[i][1]); +- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, +- RS690_cp_microcode[i][0]); +- } ++ fw_name = FIRMWARE_RS690; + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || +@@ -388,11 +383,41 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) { + DRM_INFO("Loading R500 Microcode\n"); +- for (i = 0; i < 256; i++) { ++ fw_name = FIRMWARE_R520; ++ } ++ ++ err = request_firmware(&dev_priv->fw, fw_name, &pdev->dev); ++ platform_device_unregister(pdev); ++ if (err) { ++ printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", ++ fw_name); ++ } else if (dev_priv->fw->size % 8) { ++ printk(KERN_ERR ++ "radeon_cp: Bogus length %zu in firmware \"%s\"\n", ++ dev_priv->fw->size, fw_name); ++ err = -EINVAL; ++ release_firmware(dev_priv->fw); ++ dev_priv->fw = NULL; ++ } ++ return err; ++} ++ ++static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv) ++{ ++ const __be32 *fw_data; ++ int i, size; ++ ++ radeon_do_wait_for_idle(dev_priv); ++ ++ if (dev_priv->fw) { ++ size = dev_priv->fw->size / 4; ++ fw_data = (const __be32 *)&dev_priv->fw->data[0]; ++ RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); ++ for (i = 0; i < size; i += 2) { + RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, +- R520_cp_microcode[i][1]); ++ be32_to_cpup(&fw_data[i])); + RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, +- R520_cp_microcode[i][0]); ++ be32_to_cpup(&fw_data[i + 1])); + } + } + } +@@ -1216,6 +1241,14 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) + radeon_set_pcigart(dev_priv, 1); + } + ++ if (!dev_priv->fw) { ++ int err = radeon_cp_init_microcode(dev_priv); ++ if (err) { ++ DRM_ERROR("Failed to load firmware!\n"); ++ radeon_do_cleanup_cp(dev); ++ return err; ++ } ++ } + radeon_cp_load_microcode(dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv); + +@@ -1442,6 +1475,10 @@ void radeon_do_release(struct drm_device * dev) + + /* deallocate kernel resources */ + radeon_do_cleanup_cp(dev); ++ if (dev_priv->fw) { ++ release_firmware(dev_priv->fw); ++ dev_priv->fw = NULL; ++ } + } + } + +diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h +index 3bbb871..51984d7 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.h ++++ b/drivers/gpu/drm/radeon/radeon_drv.h +@@ -31,6 +31,9 @@ + #ifndef __RADEON_DRV_H__ + #define __RADEON_DRV_H__ + ++#include ++#include ++ + /* General customization: + */ + +@@ -317,6 +320,9 @@ typedef struct drm_radeon_private { + int num_gb_pipes; + int track_flush; + drm_local_map_t *mmio; ++ ++ /* firmware */ ++ const struct firmware *fw; + } drm_radeon_private_t; + + typedef struct drm_radeon_buf_priv { +-- +1.6.1.3 + diff --git a/debian/patches/features/all/drivers-net-tehuti-request_firmware.patch b/debian/patches/features/all/drivers-net-tehuti-request_firmware.patch new file mode 100644 index 000000000..5124aee2c --- /dev/null +++ b/debian/patches/features/all/drivers-net-tehuti-request_firmware.patch @@ -0,0 +1,131 @@ +From de21b16293fc9251aa28f501c8fb2399298cc6b3 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 22 Feb 2009 19:22:39 +0000 +Subject: [PATCH 06/18] tehuti: Use request_firmware() + +Firmware blob is little endian. + +Compile-tested only. +--- + drivers/net/Kconfig | 2 +- + drivers/net/tehuti.c | 39 ++++++++++++++++++++++----------------- + drivers/net/tehuti.h | 1 + + 3 files changed, 24 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index 8ea6b4f..9e78152 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -2584,7 +2584,7 @@ config MLX4_DEBUG + config TEHUTI + tristate "Tehuti Networks 10G Ethernet" + depends on PCI +- depends on BROKEN ++ select FW_LOADER + help + Tehuti Networks 10G Ethernet NIC + +diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c +index a7a4dc4..934d976 100644 +--- a/drivers/net/tehuti.c ++++ b/drivers/net/tehuti.c +@@ -63,7 +63,6 @@ + */ + + #include "tehuti.h" +-#include "tehuti_fw.h" + + static struct pci_device_id __devinitdata bdx_pci_tbl[] = { + {0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +@@ -318,28 +317,41 @@ static int bdx_poll(struct napi_struct *napi, int budget) + + static int bdx_fw_load(struct bdx_priv *priv) + { ++ const struct firmware *fw = NULL; + int master, i; ++ int rc; + + ENTER; + master = READ_REG(priv, regINIT_SEMAPHORE); + if (!READ_REG(priv, regINIT_STATUS) && master) { +- bdx_tx_push_desc_safe(priv, s_firmLoad, sizeof(s_firmLoad)); ++ rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev); ++ if (rc) ++ goto out; ++ bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size); + mdelay(100); + } + for (i = 0; i < 200; i++) { +- if (READ_REG(priv, regINIT_STATUS)) +- break; ++ if (READ_REG(priv, regINIT_STATUS)) { ++ rc = 0; ++ goto out; ++ } + mdelay(2); + } ++ rc = -EIO; ++out: + if (master) + WRITE_REG(priv, regINIT_SEMAPHORE, 1); ++ if (fw) ++ release_firmware(fw); + +- if (i == 200) { ++ if (rc) { + ERR("%s: firmware loading failed\n", priv->ndev->name); +- DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n", +- READ_REG(priv, regVPC), +- READ_REG(priv, regVIC), READ_REG(priv, regINIT_STATUS), i); +- RET(-EIO); ++ if (rc == -EIO) ++ DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n", ++ READ_REG(priv, regVPC), ++ READ_REG(priv, regVIC), ++ READ_REG(priv, regINIT_STATUS), i); ++ RET(rc); + } else { + DBG("%s: firmware loading success\n", priv->ndev->name); + RET(0); +@@ -617,13 +629,6 @@ err: + RET(rc); + } + +-static void __init bdx_firmware_endianess(void) +-{ +- int i; +- for (i = 0; i < ARRAY_SIZE(s_firmLoad); i++) +- s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]); +-} +- + static int bdx_range_check(struct bdx_priv *priv, u32 offset) + { + return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ? +@@ -2501,7 +2506,6 @@ static void __init print_driver_id(void) + static int __init bdx_module_init(void) + { + ENTER; +- bdx_firmware_endianess(); + init_txd_sizes(); + print_driver_id(); + RET(pci_register_driver(&bdx_pci_driver)); +@@ -2521,3 +2525,4 @@ module_exit(bdx_module_exit); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR(DRIVER_AUTHOR); + MODULE_DESCRIPTION(BDX_DRV_DESC); ++MODULE_FIRMWARE("tehuti/firmware.bin"); +diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h +index efaf84d..dec67e0 100644 +--- a/drivers/net/tehuti.h ++++ b/drivers/net/tehuti.h +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + + /* Compile Time Switches */ +-- +1.6.1.3 + diff --git a/debian/patches/features/all/drivers-net-typhoon-request_firmware.patch b/debian/patches/features/all/drivers-net-typhoon-request_firmware.patch new file mode 100644 index 000000000..81bc48bb9 --- /dev/null +++ b/debian/patches/features/all/drivers-net-typhoon-request_firmware.patch @@ -0,0 +1,96 @@ +From 410a5105f5ad7d89bdbd1142a6b27937696b858f Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 22 Feb 2009 19:25:27 +0000 +Subject: [PATCH 09/18] typhoon: Use request_firmware() + +Based on a patch by Jaswinder Singh . + +Compile-tested only. +--- + drivers/net/Kconfig | 2 +- + drivers/net/typhoon.c | 23 +++++++++++++++++------ + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index c639aea..334472d 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -733,7 +733,7 @@ config VORTEX + config TYPHOON + tristate "3cr990 series \"Typhoon\" support" + depends on NET_VENDOR_3COM && PCI +- depends on BROKEN ++ select FW_LOADER + select CRC32 + ---help--- + This option enables driver support for the 3cr990 series of cards: +diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c +index 3af9a95..83226a2 100644 +--- a/drivers/net/typhoon.c ++++ b/drivers/net/typhoon.c +@@ -129,16 +129,18 @@ static const int multicast_filter_limit = 32; + #include + #include + #include ++#include + + #include "typhoon.h" +-#include "typhoon-firmware.h" + + static char version[] __devinitdata = + "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + ++#define FIRMWARE_NAME "3com/typhoon.bin" + MODULE_AUTHOR("David Dillow "); + MODULE_VERSION(DRV_MODULE_VERSION); + MODULE_LICENSE("GPL"); ++MODULE_FIRMWARE(FIRMWARE_NAME); + MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)"); + MODULE_PARM_DESC(rx_copybreak, "Packets smaller than this are copied and " + "the buffer given back to the NIC. Default " +@@ -1349,9 +1351,10 @@ typhoon_download_firmware(struct typhoon *tp) + { + void __iomem *ioaddr = tp->ioaddr; + struct pci_dev *pdev = tp->pdev; +- struct typhoon_file_header *fHdr; +- struct typhoon_section_header *sHdr; +- u8 *image_data; ++ const struct firmware *fw; ++ const struct typhoon_file_header *fHdr; ++ const struct typhoon_section_header *sHdr; ++ const u8 *image_data; + void *dpage; + dma_addr_t dpage_dma; + __sum16 csum; +@@ -1365,11 +1368,18 @@ typhoon_download_firmware(struct typhoon *tp) + int i; + int err; + ++ err = request_firmware(&fw, FIRMWARE_NAME, &tp->pdev->dev); ++ if (err) { ++ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", ++ tp->name, FIRMWARE_NAME); ++ return err; ++ } ++ + err = -EINVAL; +- fHdr = (struct typhoon_file_header *) typhoon_firmware_image; ++ fHdr = (struct typhoon_file_header *) fw->data; + image_data = (u8 *) fHdr; + +- if(memcmp(fHdr->tag, "TYPHOON", 8)) { ++ if(fw->size < sizeof(*fHdr) || memcmp(fHdr->tag, "TYPHOON", 8)) { + printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name); + goto err_out; + } +@@ -1491,6 +1501,7 @@ err_out_irq: + pci_free_consistent(pdev, PAGE_SIZE, dpage, dpage_dma); + + err_out: ++ release_firmware(fw); + return err; + } + +-- +1.6.1.3 + diff --git a/debian/patches/features/all/drivers-scsi-qla1280-request_firmware.patch b/debian/patches/features/all/drivers-scsi-qla1280-request_firmware.patch new file mode 100644 index 000000000..462af0d6b --- /dev/null +++ b/debian/patches/features/all/drivers-scsi-qla1280-request_firmware.patch @@ -0,0 +1,296 @@ +From 8217f31fa9232dad67b0d596e9f7e6678ad44616 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sat, 18 Oct 2008 16:43:31 +0100 +Subject: [PATCH 24/24] qla1280: use request_firmware + +Based on patch by Jaswinder Singh +and David Woodhouse + +Firmware blob is little endian looks like this... + unsigned char Version1 + unsigned char Version2 + unsigned char Version3 + unsigned char Padding + unsigned short start_address + unsigned short data +--- + drivers/scsi/Kconfig | 2 +- + drivers/scsi/qla1280.c | 116 +++++++++++++++++++++++++++++++----------------- + drivers/scsi/qla1280.h | 6 +++ + 3 files changed, 82 insertions(+), 42 deletions(-) + +diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig +index 3d97641..0fca0d2 100644 +--- a/drivers/scsi/Kconfig ++++ b/drivers/scsi/Kconfig +@@ -1328,7 +1328,7 @@ config SCSI_QLOGIC_FAS + config SCSI_QLOGIC_1280 + tristate "Qlogic QLA 1240/1x80/1x160 SCSI support" + depends on PCI && SCSI +- depends on BROKEN ++ select FW_LOADER + help + Say Y if you have a QLogic ISP1240/1x80/1x160 SCSI host adapter. + +diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c +index b6cd12b..5536676 100644 +--- a/drivers/scsi/qla1280.c ++++ b/drivers/scsi/qla1280.c +@@ -348,6 +348,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -384,11 +385,7 @@ + #define MEMORY_MAPPED_IO 1 + #endif + +-#define UNIQUE_FW_NAME + #include "qla1280.h" +-#include "ql12160_fw.h" /* ISP RISC codes */ +-#include "ql1280_fw.h" +-#include "ql1040_fw.h" + + #ifndef BITS_PER_LONG + #error "BITS_PER_LONG not defined!" +@@ -541,10 +538,7 @@ __setup("qla1280=", qla1280_setup); + struct qla_boards { + unsigned char name[9]; /* Board ID String */ + int numPorts; /* Number of SCSI ports */ +- unsigned short *fwcode; /* pointer to FW array */ +- unsigned short *fwlen; /* number of words in array */ +- unsigned short *fwstart; /* start address for F/W */ +- unsigned char *fwver; /* Ptr to F/W version array */ ++ char *fwname; /* firmware name */ + }; + + /* NOTE: the last argument in each entry is used to index ql1280_board_tbl */ +@@ -567,19 +561,13 @@ MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl); + + static struct qla_boards ql1280_board_tbl[] = { + /* Name , Number of ports, FW details */ +- {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01, +- &fw12160i_addr01, &fw12160i_version_str[0]}, +- {"QLA1040", 1, &risc_code01[0], &risc_code_length01, +- &risc_code_addr01, &firmware_version[0]}, +- {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01, +- &fw1280ei_addr01, &fw1280ei_version_str[0]}, +- {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01, +- &fw1280ei_addr01, &fw1280ei_version_str[0]}, +- {"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01, +- &fw1280ei_addr01, &fw1280ei_version_str[0]}, +- {"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01, +- &fw12160i_addr01, &fw12160i_version_str[0]}, +- {" ", 0} ++ {"QLA12160", 2, "qlogic/12160.bin"}, ++ {"QLA1040", 1, "qlogic/1040.bin"}, ++ {"QLA1080", 1, "qlogic/1280.bin"}, ++ {"QLA1240", 2, "qlogic/1280.bin"}, ++ {"QLA1280", 2, "qlogic/1280.bin"}, ++ {"QLA10160", 1, "qlogic/12160.bin"}, ++ {" ", 0, " "}, + }; + + static int qla1280_verbose = 1; +@@ -704,7 +692,7 @@ qla1280_info(struct Scsi_Host *host) + sprintf (bp, + "QLogic %s PCI to SCSI Host Adapter\n" + " Firmware version: %2d.%02d.%02d, Driver version %s", +- &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], ++ &bdp->name[0], ha->fwver1, ha->fwver2, ha->fwver3, + QLA1280_VERSION); + return bp; + } +@@ -1648,36 +1636,60 @@ qla1280_chip_diag(struct scsi_qla_host *ha) + static int + qla1280_load_firmware_pio(struct scsi_qla_host *ha) + { +- uint16_t risc_address, *risc_code_address, risc_code_size; ++ const struct firmware *fw; ++ const __le16 *fw_data; ++ uint16_t risc_address, risc_code_size; + uint16_t mb[MAILBOX_REGISTER_COUNT], i; + int err; + ++ err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, ++ &ha->pdev->dev); ++ if (err) { ++ printk(KERN_ERR "Failed to load image \"%s\" err %d\n", ++ ql1280_board_tbl[ha->devnum].fwname, err); ++ return err; ++ } ++ if ((fw->size % 2) || (fw->size < 6)) { ++ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", ++ fw->size, ql1280_board_tbl[ha->devnum].fwname); ++ err = -EINVAL; ++ goto out; ++ } ++ ha->fwver1 = fw->data[0]; ++ ha->fwver2 = fw->data[1]; ++ ha->fwver3 = fw->data[2]; ++ fw_data = (const __le16 *)&fw->data[0]; ++ ha->fwstart = __le16_to_cpu(fw_data[2]); ++ + /* Load RISC code. */ +- risc_address = *ql1280_board_tbl[ha->devnum].fwstart; +- risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; +- risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; ++ risc_address = ha->fwstart; ++ fw_data = (const __le16 *)&fw->data[4]; ++ risc_code_size = (fw->size - 6) / 2; + + for (i = 0; i < risc_code_size; i++) { + mb[0] = MBC_WRITE_RAM_WORD; + mb[1] = risc_address + i; +- mb[2] = risc_code_address[i]; ++ mb[2] = __le16_to_cpu(fw_data[i]); + + err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb); + if (err) { + printk(KERN_ERR "scsi(%li): Failed to load firmware\n", + ha->host_no); +- return err; ++ goto out; + } + } +- +- return 0; ++out: ++ release_firmware(fw); ++ return err; + } + + #define DUMP_IT_BACK 0 /* for debug of RISC loading */ + static int + qla1280_load_firmware_dma(struct scsi_qla_host *ha) + { +- uint16_t risc_address, *risc_code_address, risc_code_size; ++ const struct firmware *fw; ++ const __le16 *fw_data; ++ uint16_t risc_address, risc_code_size; + uint16_t mb[MAILBOX_REGISTER_COUNT], cnt; + int err = 0, num, i; + #if DUMP_IT_BACK +@@ -1689,10 +1701,29 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) + return -ENOMEM; + #endif + ++ err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, ++ &ha->pdev->dev); ++ if (err) { ++ printk(KERN_ERR "Failed to load image \"%s\" err %d\n", ++ ql1280_board_tbl[ha->devnum].fwname, err); ++ return err; ++ } ++ if ((fw->size % 2) || (fw->size < 6)) { ++ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", ++ fw->size, ql1280_board_tbl[ha->devnum].fwname); ++ err = -EINVAL; ++ goto out; ++ } ++ ha->fwver1 = fw->data[0]; ++ ha->fwver2 = fw->data[1]; ++ ha->fwver3 = fw->data[2]; ++ fw_data = (const __le16 *)&fw->data[0]; ++ ha->fwstart = __le16_to_cpu(fw_data[2]); ++ + /* Load RISC code. */ +- risc_address = *ql1280_board_tbl[ha->devnum].fwstart; +- risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; +- risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; ++ risc_address = ha->fwstart; ++ fw_data = (const __le16 *)&fw->data[4]; ++ risc_code_size = (fw->size - 6) / 2; + + dprintk(1, "%s: DMA RISC code (%i) words\n", + __func__, risc_code_size); +@@ -1708,10 +1739,9 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) + + dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p)," + "%d,%d(0x%x)\n", +- risc_code_address, cnt, num, risc_address); ++ fw_data, cnt, num, risc_address); + for(i = 0; i < cnt; i++) +- ((__le16 *)ha->request_ring)[i] = +- cpu_to_le16(risc_code_address[i]); ++ ((__le16 *)ha->request_ring)[i] = fw_data[i]; + + mb[0] = MBC_LOAD_RAM; + mb[1] = risc_address; +@@ -1763,7 +1793,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) + #endif + risc_address += cnt; + risc_code_size = risc_code_size - cnt; +- risc_code_address = risc_code_address + cnt; ++ fw_data = fw_data + cnt; + num++; + } + +@@ -1771,6 +1801,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) + #if DUMP_IT_BACK + pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); + #endif ++ release_firmware(fw); + return err; + } + +@@ -1786,7 +1817,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) + /* Verify checksum of loaded RISC code. */ + mb[0] = MBC_VERIFY_CHECKSUM; + /* mb[1] = ql12_risc_code_addr01; */ +- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; ++ mb[1] = ha->fwstart; + err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb); + if (err) { + printk(KERN_ERR "scsi(%li): RISC checksum failed.\n", ha->host_no); +@@ -1796,7 +1827,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) + /* Start firmware execution. */ + dprintk(1, "%s: start firmware running.\n", __func__); + mb[0] = MBC_EXECUTE_FIRMWARE; +- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; ++ mb[1] = ha->fwstart; + err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); + if (err) { + printk(KERN_ERR "scsi(%li): Failed to start firmware\n", +@@ -1821,7 +1852,7 @@ qla1280_load_firmware(struct scsi_qla_host *ha) + if (err) + goto out; + err = qla1280_start_firmware(ha); +- out: ++out: + return err; + } + +@@ -4451,6 +4482,9 @@ module_exit(qla1280_exit); + MODULE_AUTHOR("Qlogic & Jes Sorensen"); + MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver"); + MODULE_LICENSE("GPL"); ++MODULE_FIRMWARE("qlogic/1040.bin"); ++MODULE_FIRMWARE("qlogic/1280.bin"); ++MODULE_FIRMWARE("qlogic/12160.bin"); + MODULE_VERSION(QLA1280_VERSION); + + /* +diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h +index ff2c363..d7c44b8 100644 +--- a/drivers/scsi/qla1280.h ++++ b/drivers/scsi/qla1280.h +@@ -1069,6 +1069,12 @@ struct scsi_qla_host { + + struct nvram nvram; + int nvram_valid; ++ ++ /* Firmware Info */ ++ unsigned short fwstart; /* start address for F/W */ ++ unsigned char fwver1; /* F/W version first char */ ++ unsigned char fwver2; /* F/W version second char */ ++ unsigned char fwver3; /* F/W version third char */ + }; + + #endif /* _QLA1280_H */ +-- +1.6.1.3 + diff --git a/debian/patches/series/1~experimental.1 b/debian/patches/series/1~experimental.1 index ca89b7247..d49e084d0 100644 --- a/debian/patches/series/1~experimental.1 +++ b/debian/patches/series/1~experimental.1 @@ -8,6 +8,12 @@ #+ debian/dfsg/drivers-net-bnx2-request_firmware-1.patch #+ features/all/drivers-net-acenic-firmwar_request.patch ++ features/all/drivers-gpu-drm-mga-request_firmware.patch ++ features/all/drivers-gpu-drm-r128-request_firmware.patch ++ features/all/drivers-gpu-drm-radeon-request_firmware.patch ++ features/all/drivers-net-tehuti-request_firmware.patch ++ features/all/drivers-net-typhoon-request_firmware.patch ++ features/all/drivers-scsi-qla1280-request_firmware.patch + features/all/export-gfs2-locking-symbols.patch + features/all/export-unionfs-symbols.patch diff --git a/debian/patches/series/orig-0 b/debian/patches/series/orig-0 index 4503ec9b4..b8f393bf6 100644 --- a/debian/patches/series/orig-0 +++ b/debian/patches/series/orig-0 @@ -1,10 +1,16 @@ -X debian/dfsg/files-1 ++ debian/dfsg/drivers-gpu-drm-mga-disable.patch ++ debian/dfsg/drivers-gpu-drm-r128-disable.patch ++ debian/dfsg/drivers-gpu-drm-radeon-disable.patch + debian/dfsg/drivers-net-bnx2-disable.patch + debian/dfsg/drivers-net-bnx2x-disable.patch + debian/dfsg/drivers-net-appletalk-cops.patch + debian/dfsg/drivers-net-hamradio-yam.patch + debian/dfsg/drivers-net-myri.patch ++ debian/dfsg/drivers-net-tehuti-disable.patch + debian/dfsg/drivers-net-tokenring-3c359-smctr.patch ++ debian/dfsg/drivers-net-typhoon-disable.patch ++ debian/dfsg/drivers-scsi-qla1280-disable.patch + debian/dfsg/drivers-scsi-qlogicpti.patch + debian/dfsg/firmware-cleanup.patch + debian/dfsg/sound-pci.patch +X debian/dfsg/files-1